Альдаципедия aczwiki https://acz.skywiki.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0 MediaWiki 1.43.1 first-letter Медиа Служебная Обсуждение Участник Обсуждение участника Альдаципедия Альдаципедия talk Файл Обсуждение файла MediaWiki Обсуждение MediaWiki Шаблон Обсуждение шаблона Справка Обсуждение справки Категория Обсуждение категории Video Video talk Campaign Campaign talk Модуль Обсуждение модуля Шаблон:Str len 10 47 104 2013-03-14T14:34:59Z wikipedia, ruwikipedia>DR 0 wikitext text/x-wiki {{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 95f10258d5214440d2706952656564f216c2e4cc Шаблон:Str rep 10 81 172 2015-02-28T09:38:11Z wikipedia, ruwikipedia>Rubinbot II 0 Защищена Шаблон:Str rep: Top used templates to be protected ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессро wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|{{{4|1}}}}}</includeonly><noinclude>{{doc}}</noinclude> c75032f150c372324c69a6f62ff4ab1492ad4cfa Шаблон:Lang-fi 10 101 212 2015-06-22T08:43:43Z wikipedia, ruwikipedia>DimaABot 0 Бот: удаление категории по запросу на [[ВП:РДБ]] wikitext text/x-wiki [[финский язык|фин.]] {{langi|fi|{{{1}}}}}<noinclude>{{doc|Lang/doc}} </noinclude> 16ac91b8e1e294e7687d57c0757c178f9662581c Модуль:Namespace detect/data 828 23 56 2015-06-27T21:11:34Z wikipedia, ruwikipedia>Draa kul 0 Защищена Модуль:Namespace detect/data: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато… Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect data -- -- This module holds data for [[Module:Namespace detect]] to be loaded per -- -- page, rather than per #invoke, for performance reasons. -- -------------------------------------------------------------------------------- local cfg = require('Module:Namespace detect/config') local function addKey(t, key, defaultKey) if key ~= defaultKey then t[#t + 1] = key end end -- Get a table of parameters to query for each default parameter name. -- This allows wikis to customise parameter names in the cfg table while -- ensuring that default parameter names will always work. The cfg table -- values can be added as a string, or as an array of strings. local defaultKeys = { 'main', 'talk', 'other', 'subjectns', 'demospace', 'demopage' } local argKeys = {} for i, defaultKey in ipairs(defaultKeys) do argKeys[defaultKey] = {defaultKey} end for defaultKey, t in pairs(argKeys) do local cfgValue = cfg[defaultKey] local cfgValueType = type(cfgValue) if cfgValueType == 'string' then addKey(t, cfgValue, defaultKey) elseif cfgValueType == 'table' then for i, key in ipairs(cfgValue) do addKey(t, key, defaultKey) end end cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more. end local function getParamMappings() --[[ -- Returns a table of how parameter names map to namespace names. The keys -- are the actual namespace names, in lower case, and the values are the -- possible parameter names for that namespace, also in lower case. The -- table entries are structured like this: -- { -- [''] = {'main'}, -- ['wikipedia'] = {'wikipedia', 'project', 'wp'}, -- ... -- } --]] local mappings = {} local mainNsName = mw.site.subjectNamespaces[0].name mainNsName = mw.ustring.lower(mainNsName) mappings[mainNsName] = mw.clone(argKeys.main) mappings['talk'] = mw.clone(argKeys.talk) for nsid, ns in pairs(mw.site.subjectNamespaces) do if nsid ~= 0 then -- Exclude main namespace. local nsname = mw.ustring.lower(ns.name) local canonicalName = mw.ustring.lower(ns.canonicalName) mappings[nsname] = {nsname} if canonicalName ~= nsname then table.insert(mappings[nsname], canonicalName) end for _, alias in ipairs(ns.aliases) do table.insert(mappings[nsname], mw.ustring.lower(alias)) end end end return mappings end return { argKeys = argKeys, cfg = cfg, mappings = getParamMappings() } d224f42a258bc308ef3ad8cc8686cd7a4f47d005 Модуль:Namespace detect/config 828 24 58 2015-06-27T21:11:46Z wikipedia, ruwikipedia>Draa kul 0 Защищена Модуль:Namespace detect/config: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрат… Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect configuration data -- -- -- -- This module stores configuration data for Module:Namespace detect. Here -- -- you can localise the module to your wiki's language. -- -- -- -- To activate a configuration item, you need to uncomment it. This means -- -- that you need to remove the text "-- " at the start of the line. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. Values added -- -- here will work in addition to the default English parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- cfg.foo = 'parameter name' -- -- -- -- To add multiple names, you can use this format: -- -- -- -- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} -- -------------------------------------------------------------------------------- ---- This parameter displays content for the main namespace: -- cfg.main = 'main' ---- This parameter displays in talk namespaces: -- cfg.talk = 'talk' ---- This parameter displays content for "other" namespaces (namespaces for which ---- parameters have not been specified): -- cfg.other = 'other' ---- This parameter makes talk pages behave as though they are the corresponding ---- subject namespace. Note that this parameter is used with [[Module:Yesno]]. ---- Edit that module to change the default values of "yes", "no", etc. -- cfg.subjectns = 'subjectns' ---- This parameter sets a demonstration namespace: -- cfg.demospace = 'demospace' ---- This parameter sets a specific page to compare: cfg.demopage = 'page' -------------------------------------------------------------------------------- -- Table configuration -- -- These configuration items allow customisation of the "table" function, -- -- used to generate a table of possible parameters in the module -- -- documentation. -- -------------------------------------------------------------------------------- ---- The header for the namespace column in the wikitable containing the list of ---- possible subject-space parameters. -- cfg.wikitableNamespaceHeader = 'Namespace' ---- The header for the wikitable containing the list of possible subject-space ---- parameters. -- cfg.wikitableAliasesHeader = 'Aliases' -------------------------------------------------------------------------------- -- End of configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 0e4ff08d13c4b664d66b32c232deb129b77c1a56 Модуль:Color contrast/colors 828 35 80 2016-06-19T09:05:16Z wikipedia, ruwikipedia>Dima st bk 0 Защищена Модуль:Color contrast/colors: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато… Scribunto text/plain return { aliceblue = 0.92880068253475, antiquewhite = 0.84646951707754, aqua = 0.7874, aquamarine = 0.8078549208338, azure = 0.97265264954166, beige = 0.8988459998705, bisque = 0.80732327372979, black = 0, blanchedalmond = 0.85084439608156, blue = 0.0722, blueviolet = 0.12622014321946, brown = 0.098224287876511, burlywood = 0.51559844533893, cadetblue = 0.29424681085422, chartreuse = 0.76032025902623, chocolate = 0.23898526114557, coral = 0.37017930872924, cornflowerblue = 0.30318641994179, cornsilk = 0.93562110372965, crimson = 0.16042199953026, cyan = 0.7874, darkblue = 0.018640801980939, darkcyan = 0.20329317839046, darkgoldenrod = 0.27264703559993, darkgray = 0.39675523072563, darkgreen = 0.091143429047575, darkgrey = 0.39675523072563, darkkhaki = 0.45747326349994, darkmagenta = 0.07353047651207, darkolivegreen = 0.12651920884889, darkorange = 0.40016167026524, darkorchid = 0.13413142174857, darkred = 0.054889674531132, darksalmon = 0.40541471563381, darkseagreen = 0.43789249325969, darkslateblue = 0.065792846227988, darkslategray = 0.067608151928044, darkslategrey = 0.067608151928044, darkturquoise = 0.4874606277449, darkviolet = 0.10999048339343, deeppink = 0.23866895828276, deepskyblue = 0.44481603395575, dimgray = 0.14126329114027, dimgrey = 0.14126329114027, dodgerblue = 0.27442536991456, firebrick = 0.10724525535015, floralwhite = 0.95922484825004, forestgreen = 0.18920812076002, fuchsia = 0.2848, gainsboro = 0.71569350050648, ghostwhite = 0.94311261886323, gold = 0.69860877428159, goldenrod = 0.41919977809569, gray = 0.2158605001139, green = 0.15438342968146, greenyellow = 0.80609472611453, grey = 0.2158605001139, honeydew = 0.96336535554782, hotpink = 0.34658438169715, indianred = 0.21406134963884, indigo = 0.03107561486337, ivory = 0.99071270600615, khaki = 0.77012343394121, lavender = 0.80318750514521, lavenderblush = 0.90172748631046, lawngreen = 0.73905893124963, lemonchiffon = 0.94038992245622, lightblue = 0.63709141280807, lightcoral = 0.35522120733135, lightcyan = 0.94587293494829, lightgoldenrodyellow = 0.93348351018297, lightgray = 0.65140563741982, lightgreen = 0.69091979956865, lightgrey = 0.65140563741982, lightpink = 0.58566152734898, lightsalmon = 0.4780675225206, lightseagreen = 0.35050145117042, lightskyblue = 0.56195637618331, lightslategray = 0.23830165007287, lightslategrey = 0.23830165007287, lightsteelblue = 0.53983888284666, lightyellow = 0.98161818392882, lime = 0.7152, limegreen = 0.44571042246098, linen = 0.88357340984379, magenta = 0.2848, maroon = 0.045891942324215, mediumaquamarine = 0.49389703310801, mediumblue = 0.044077780212328, mediumorchid = 0.21639251153773, mediumpurple = 0.22905858091648, mediumseagreen = 0.34393112338131, mediumslateblue = 0.20284629471622, mediumspringgreen = 0.70704308194184, mediumturquoise = 0.5133827926448, mediumvioletred = 0.14371899849357, midnightblue = 0.02071786635086, mintcream = 0.97834604947588, mistyrose = 0.82183047859185, moccasin = 0.80083000991567, navajowhite = 0.76519682342785, navy = 0.015585128108224, oldlace = 0.91900633405549, olive = 0.20027537200568, olivedrab = 0.22593150951929, orange = 0.4817026703631, orangered = 0.25516243753416, orchid = 0.31348806761439, palegoldenrod = 0.78792647887614, palegreen = 0.77936759006353, paleturquoise = 0.76436077921714, palevioletred = 0.28754994117889, papayawhip = 0.87797100199835, peachpuff = 0.74905589878251, peru = 0.30113074877936, pink = 0.63271070702466, plum = 0.45734221587969, powderblue = 0.68254586500605, purple = 0.061477070432439, rebeccapurple = 0.07492341159447, red = 0.2126, rosybrown = 0.32319457649407, royalblue = 0.16663210743188, saddlebrown = 0.097922285020521, salmon = 0.36977241527596, sandybrown = 0.46628543696283, seagreen = 0.19734199706275, seashell = 0.92737862206922, sienna = 0.13697631337098, silver = 0.52711512570581, skyblue = 0.55291668518184, slateblue = 0.14784278062136, slategray = 0.20896704076536, slategrey = 0.20896704076536, snow = 0.96533341834849, springgreen = 0.73052306068529, steelblue = 0.20562642207625, tan = 0.48237604163921, teal = 0.16996855778968, thistle = 0.56818401093733, tomato = 0.30638612719415, turquoise = 0.5895536427578, violet = 0.40315452986676, wheat = 0.74909702820482, white = 1, whitesmoke = 0.91309865179342, yellow = 0.9278, yellowgreen = 0.50762957208707, } 6ae47fdb24de4eed5ec26d203faf5341a388987b Шаблон:Население государства 10 100 210 2016-08-16T20:27:21Z wikipedia, ruwikipedia>SandBot 0 /* top */удаление устаревшего ключа сортировки wikitext text/x-wiki <includeonly>{{#switch: {{{1}}} | Республика Южная Осетия = Население Южной Осетии{{!}}Население | Население }}</includeonly><noinclude> {{doc}} [[Категория:Шаблоны по странам]] </noinclude> e0568280ef5056e94f5f1abf1934f4188a52c35f Шаблон:Nobr 10 86 182 2016-12-02T13:15:38Z wikipedia, ruwikipedia>Jack who built the house 0 используем класс nowrap wikitext text/x-wiki <includeonly><span class="nowrap">{{{1}}}</span></includeonly><noinclude> {{doc}} <!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --> </noinclude> 989c6f164ed3a8543e916c8f1746ba1ab94fb068 Шаблон:Без уточнения 10 77 164 2017-03-12T19:54:44Z wikipedia, ruwikipedia>Jack who built the house 0 бoлee кoppeктный пaттepн; нaпpимep, в «Haзвaниe (нeyтoчнeниe) (yтoчнeниe)» yтoчнeниeм дoлжнa cчитaтьcя тoлькo пocлeдняя чacть. вoзмoжнocть иcпол. бeз 1-гo пap. и пoдcтaн. wikitext text/x-wiki <includeonly>{{ {{{|safesubst:}}}#invoke:String|replace|{{{1|{{ {{{|safesubst:}}}PAGENAME}}}}}|^%s*(.+)%s+%b()%s*$|%1||false}}</includeonly><noinclude>{{doc}}</noinclude> 1fcb3edb0be49656ae0f913e9a8fb4853264b480 Шаблон:Карточка/название 10 76 162 2017-08-01T19:26:37Z wikipedia, ruwikipedia>Q-bit array 0 Защитил «[[Шаблон:Карточка/название]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только адм… wikitext text/x-wiki {{#if:{{{1|}}}|{{{1}}}|{{без уточнения|{{PAGENAME}}}}}}<noinclude> {{doc}} </noinclude> 110edc6d8286f120a048863c68371720bd4e65ca Модуль:Category handler/config 828 20 50 2017-08-01T19:26:42Z wikipedia, ruwikipedia>Q-bit array 0 Защитил «[[Модуль:Category handler/config]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист… Scribunto text/plain -------------------------------------------------------------------------------- -- [[Module:Category handler]] configuration data -- -- Language-specific parameter names and values can be set here. -- -- For blacklist config, see [[Module:Category handler/blacklist]]. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Start configuration data -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- foo = 'parameter name', -- -- -- -- To add multiple names, you can use this format: -- -- -- -- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, -- -------------------------------------------------------------------------------- cfg.parameters = { -- The nocat and categories parameter suppress -- categorisation. They are used with Module:Yesno, and work as follows: -- -- cfg.nocat: -- Result of yesno() Effect -- true Categorisation is suppressed -- false Categorisation is allowed, and -- the blacklist check is skipped -- nil Categorisation is allowed -- -- cfg.categories: -- Result of yesno() Effect -- true Categorisation is allowed, and -- the blacklist check is skipped -- false Categorisation is suppressed -- nil Categorisation is allowed nocat = 'nocat', categories = 'categories', -- The parameter name for the legacy "category2" parameter. This skips the -- blacklist if set to the cfg.category2Yes value, and suppresses -- categorisation if present but equal to anything other than -- cfg.category2Yes or cfg.category2Negative. category2 = 'category2', -- cfg.subpage is the parameter name to specify how to behave on subpages. subpage = 'subpage', -- The parameter for data to return in all namespaces. all = 'all', -- The parameter name for data to return if no data is specified for the -- namespace that is detected. other = 'other', -- The parameter name used to specify a page other than the current page; -- used for testing and demonstration. demopage = 'page', } -------------------------------------------------------------------------------- -- Parameter values -- -- These are set values that can be used with certain parameters. Only one -- -- value can be specified, like this: -- -- -- -- cfg.foo = 'value name' -- -- -------------------------------------------------------------------------------- -- The following settings are used with the cfg.category2 parameter. Setting -- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2 -- is present but equal to anything other than cfg.category2Yes or -- cfg.category2Negative then it supresses cateogrisation. cfg.category2Yes = 'yes' cfg.category2Negative = '¬' -- The following settings are used with the cfg.subpage parameter. -- cfg.subpageNo is the value to specify to not categorise on subpages; -- cfg.subpageOnly is the value to specify to only categorise on subpages. cfg.subpageNo = 'no' cfg.subpageOnly = 'only' -------------------------------------------------------------------------------- -- Default namespaces -- -- This is a table of namespaces to categorise by default. The keys are the -- -- namespace numbers. -- -------------------------------------------------------------------------------- cfg.defaultNamespaces = { [ 0] = true, -- main [ 6] = true, -- file [ 12] = true, -- help [ 14] = true, -- category [100] = true, -- portal [108] = true, -- book } -------------------------------------------------------------------------------- -- Wrappers -- -- This is a wrapper template or a list of wrapper templates to be passed to -- -- [[Module:Arguments]]. -- -------------------------------------------------------------------------------- cfg.wrappers = 'Template:Category handler' -------------------------------------------------------------------------------- -- End configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 373cd107b13a5b00e6a1b7e66a749f12502c849d Модуль:Category handler/blacklist 828 22 54 2017-08-01T19:26:43Z wikipedia, ruwikipedia>Q-bit array 0 Защитил «[[Модуль:Category handler/blacklist]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админис… Scribunto text/plain -- This module contains the blacklist used by [[Module:Category handler]]. -- Pages that match Lua patterns in this list will not be categorised unless -- categorisation is explicitly requested. return { '^Main Page$', -- don't categorise the main page. -- Don't categorise the following pages or their subpages. -- "%f[/\0]" matches if the next character is "/" or the end of the string. '^Wikipedia:Cascade%-protected items%f[/\0]', '^User:UBX%f[/\0]', -- The userbox "template" space. '^User talk:UBX%f[/\0]', -- Don't categorise subpages of these pages, but allow -- categorisation of the base page. '^Wikipedia:Template messages/.*$', '/[aA]rchive' -- Don't categorise archives. } c84948ad9808d5d323408d5d10d5652f748a0550 Модуль:Category handler 828 16 42 2017-08-01T19:26:45Z wikipedia, ruwikipedia>Q-bit array 0 Защитил «[[Модуль:Category handler]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато… Scribunto text/plain -------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all namespace aliases -- -- are supported, and namespace names are detected automatically for -- -- the local wiki. This module requires [[Module:Namespace detect]] -- -- and [[Module:Yesno]] to be available on the local wiki. It can be -- -- configured for different wikis by altering the values in -- -- [[Module:Category handler/config]], and pages can be blacklisted -- -- from categorisation by using [[Module:Category handler/blacklist]]. -- -- -- -------------------------------------------------------------------------------- -- Load required modules local yesno = require('Module:Yesno') -- Lazily load things we don't always need local mShared, mappings local p = {} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function trimWhitespace(s, removeBlanks) if type(s) ~= 'string' then return s end s = s:match('^%s*(.-)%s*$') if removeBlanks then if s ~= '' then return s else return nil end else return s end end -------------------------------------------------------------------------------- -- CategoryHandler class -------------------------------------------------------------------------------- local CategoryHandler = {} CategoryHandler.__index = CategoryHandler function CategoryHandler.new(data, args) local obj = setmetatable({ _data = data, _args = args }, CategoryHandler) -- Set the title object do local pagename = obj:parameter('demopage') local success, titleObj if pagename then success, titleObj = pcall(mw.title.new, pagename) end if success and titleObj then obj.title = titleObj if titleObj == mw.title.getCurrentTitle() then obj._usesCurrentTitle = true end else obj.title = mw.title.getCurrentTitle() obj._usesCurrentTitle = true end end -- Set suppression parameter values for _, key in ipairs{'nocat', 'categories'} do local value = obj:parameter(key) value = trimWhitespace(value, true) obj['_' .. key] = yesno(value) end do local subpage = obj:parameter('subpage') local category2 = obj:parameter('category2') if type(subpage) == 'string' then subpage = mw.ustring.lower(subpage) end if type(category2) == 'string' then subpage = mw.ustring.lower(category2) end obj._subpage = trimWhitespace(subpage, true) obj._category2 = trimWhitespace(category2) -- don't remove blank values end return obj end function CategoryHandler:parameter(key) local parameterNames = self._data.parameters[key] local pntype = type(parameterNames) if pntype == 'string' or pntype == 'number' then return self._args[parameterNames] elseif pntype == 'table' then for _, name in ipairs(parameterNames) do local value = self._args[name] if value ~= nil then return value end end return nil else error(string.format( 'invalid config key "%s"', tostring(key) ), 2) end end function CategoryHandler:isSuppressedByArguments() return -- See if a category suppression argument has been set. self._nocat == true or self._categories == false or ( self._category2 and self._category2 ~= self._data.category2Yes and self._category2 ~= self._data.category2Negative ) -- Check whether we are on a subpage, and see if categories are -- suppressed based on our subpage status. or self._subpage == self._data.subpageNo and self.title.isSubpage or self._subpage == self._data.subpageOnly and not self.title.isSubpage end function CategoryHandler:shouldSkipBlacklistCheck() -- Check whether the category suppression arguments indicate we -- should skip the blacklist check. return self._nocat == false or self._categories == true or self._category2 == self._data.category2Yes end function CategoryHandler:matchesBlacklist() if self._usesCurrentTitle then return self._data.currentTitleMatchesBlacklist else mShared = mShared or require('Module:Category handler/shared') return mShared.matchesBlacklist( self.title.prefixedText, mw.loadData('Module:Category handler/blacklist') ) end end function CategoryHandler:isSuppressed() -- Find if categories are suppressed by either the arguments or by -- matching the blacklist. return self:isSuppressedByArguments() or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist() end function CategoryHandler:getNamespaceParameters() if self._usesCurrentTitle then return self._data.currentTitleNamespaceParameters else if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end return mShared.getNamespaceParameters( self.title, mappings ) end end function CategoryHandler:namespaceParametersExist() -- Find whether any namespace parameters have been specified. -- We use the order "all" --> namespace params --> "other" as this is what -- the old template did. if self:parameter('all') then return true end if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end for ns, params in pairs(mappings) do for i, param in ipairs(params) do if self._args[param] then return true end end end if self:parameter('other') then return true end return false end function CategoryHandler:getCategories() local params = self:getNamespaceParameters() local nsCategory for i, param in ipairs(params) do local value = self._args[param] if value ~= nil then nsCategory = value break end end if nsCategory ~= nil or self:namespaceParametersExist() then -- Namespace parameters exist - advanced usage. if nsCategory == nil then nsCategory = self:parameter('other') end local ret = {self:parameter('all')} local numParam = tonumber(nsCategory) if numParam and numParam >= 1 and math.floor(numParam) == numParam then -- nsCategory is an integer ret[#ret + 1] = self._args[numParam] else ret[#ret + 1] = nsCategory end if #ret < 1 then return nil else return table.concat(ret) end elseif self._data.defaultNamespaces[self.title.namespace] then -- Namespace parameters don't exist, simple usage. return self._args[1] end return nil end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- Used for testing purposes. return { CategoryHandler = CategoryHandler } end function p._main(args, data) data = data or mw.loadData('Module:Category handler/data') local handler = CategoryHandler.new(data, args) if handler:isSuppressed() then return nil end return handler:getCategories() end function p.main(frame, data) data = data or mw.loadData('Module:Category handler/data') local args = require('Module:Arguments').getArgs(frame, { wrappers = data.wrappers, valueFunc = function (k, v) v = trimWhitespace(v) if type(k) == 'number' then if v ~= '' then return v else return nil end else return v end end }) return p._main(args, data) end return p b74dd63857b24904ac452429b11213f18647471f Модуль:Category handler/shared 828 21 52 2017-08-01T19:26:47Z wikipedia, ruwikipedia>Q-bit array 0 Защитил «[[Модуль:Category handler/shared]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист… Scribunto text/plain -- This module contains shared functions used by [[Module:Category handler]] -- and its submodules. local p = {} function p.matchesBlacklist(page, blacklist) for i, pattern in ipairs(blacklist) do local match = mw.ustring.match(page, pattern) if match then return true end end return false end function p.getParamMappings(useLoadData) local dataPage = 'Module:Namespace detect/data' if useLoadData then return mw.loadData(dataPage).mappings else return require(dataPage).mappings end end function p.getNamespaceParameters(titleObj, mappings) -- We don't use title.nsText for the namespace name because it adds -- underscores. local mappingsKey if titleObj.isTalkPage then mappingsKey = 'talk' else mappingsKey = mw.site.namespaces[titleObj.namespace].name end mappingsKey = mw.ustring.lower(mappingsKey) return mappings[mappingsKey] or {} end return p d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5 Модуль:Category handler/data 828 19 48 2017-08-01T19:26:49Z wikipedia, ruwikipedia>Q-bit array 0 Защитил «[[Модуль:Category handler/data]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администр… Scribunto text/plain -- This module assembles data to be passed to [[Module:Category handler]] using -- mw.loadData. This includes the configuration data and whether the current -- page matches the title blacklist. local data = require('Module:Category handler/config') local mShared = require('Module:Category handler/shared') local blacklist = require('Module:Category handler/blacklist') local title = mw.title.getCurrentTitle() data.currentTitleMatchesBlacklist = mShared.matchesBlacklist( title.prefixedText, blacklist ) data.currentTitleNamespaceParameters = mShared.getNamespaceParameters( title, mShared.getParamMappings() ) return data abbc68048ff698e88dda06b64ecf384bbf583120 Шаблон:Yesno 10 25 60 2017-08-01T19:30:50Z wikipedia, ruwikipedia>Q-bit array 0 Защитил «[[Шаблон:Yesno]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бе… wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }} |no |n |нет |false |0 = {{{no|<!-- null -->}}} | = {{{blank|{{{no|<!-- null -->}}}}}} |¬ = {{{¬|}}} |yes |y |да |true |1 = {{{yes|yes}}} |#default = {{{def|{{{yes|yes}}}}}} }}<noinclude> {{Documentation}} </noinclude> 4e236854c477d07a225c2ab6c016c389b133e8d3 Шаблон:Langi 10 75 160 2017-10-14T07:25:47Z wikipedia, ruwikipedia>Jack who built the house 0 → [[/doc]] wikitext text/x-wiki <span lang="{{{1}}}" xml:lang="{{{1}}}" style="font-style:italic;">{{{2}}}</span><noinclude>{{doc}}</noinclude> 7bb9f9098c88e770b982402adf30a3bbf645aa4b Шаблон:Lang-sv 10 99 208 2017-12-10T06:47:12Z wikipedia, ruwikipedia>Dima st bk 0 langi wikitext text/x-wiki [[шведский язык|швед.]] {{langi|sv|{{{1}}}}}<noinclude>{{doc|Lang/doc}} </noinclude> c4b5e81c6405972dcea4cc26ab77e99e9bd2021f Модуль:Arguments 828 10 30 2018-01-12T21:01:04Z wikipedia, ruwikipedia>Grain of sand 0 sandbox → песочница Scribunto text/plain -- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val == '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) == 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) == 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end local function matchesTitle(given, title) local tp = type( given ) return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title end local translate_mt = { __index = function(t, k) return k end } function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} --[[ -- Set up argument translation. --]] options.translate = options.translate or {} if getmetatable(options.translate) == nil then setmetatable(options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} for k,v in pairs(options.translate) do options.backtranslate[v] = k end end if options.backtranslate and getmetatable(options.backtranslate) == nil then setmetatable(options.backtranslate, { __index = function(t, k) if options.translate[k] ~= k then return nil else return k end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] local fargs, pargs, luaArgs if type(frame.args) == 'table' and type(frame.getParent) == 'function' then if options.wrappers then --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] local parent = frame:getParent() if not parent then fargs = frame.args else local title = parent:getTitle():gsub('/песочница$', '') local found = false if matchesTitle(options.wrappers, title) then found = true elseif type(options.wrappers) == 'table' then for _,v in pairs(options.wrappers) do if matchesTitle(v, title) then found = true break end end end -- We test for false specifically here so that nil (the default) acts like true. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else -- options.wrapper isn't set, so check the other options. if not options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame:getParent() pargs = parent and parent.args or nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. local argTables = {fargs} argTables[#argTables + 1] = pargs argTables[#argTables + 1] = luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error( "bad value assigned to option 'valueFunc'" .. '(function expected, got ' .. type(tidyVal) .. ')', 2 ) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable(args, metatable) local function mergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for _, t in ipairs(tables) do for key, val in pairs(t) do if metaArgs[key] == nil and nilArgs[key] ~= 'h' then local tidiedVal = tidyVal(key, val) if tidiedVal == nil then nilArgs[key] = 's' else metaArgs[key] = tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index = function (t, key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] if type(key) == 'string' then key = options.translate[key] end local val = metaArgs[key] if val ~= nil then return val elseif metatable.donePairs or nilArgs[key] then return nil end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTable[key]) if argTableVal ~= nil then metaArgs[key] = argTableVal return argTableVal end end nilArgs[key] = 'h' return nil end metatable.__newindex = function (t, key, val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. if type(key) == 'string' then key = options.translate[key] end if options.readOnly then error( 'could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2 ) elseif options.noOverwrite and args[key] ~= nil then error( 'could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2 ) elseif val == nil then --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key] = nil nilArgs[key] = 'h' else metaArgs[key] = val end end local function translatenext(invariant) local k, v = next(invariant.t, invariant.k) invariant.k = k if k == nil then return nil elseif type(k) ~= 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate[k] if backtranslate == nil then -- Skip this one. This is a tail call, so this won't cause stack overflow return translatenext(invariant) else return backtranslate, v end end end metatable.__pairs = function () -- Called when pairs is run on the args table. if not metatable.donePairs then mergeArgs(argTables) metatable.donePairs = true end return translatenext, { t = metaArgs } end local function inext(t, i) -- This uses our __index metamethod local v = t[i + 1] if v ~= nil then return i + 1, v end end metatable.__ipairs = function (t) -- Called when ipairs is run on the args table. return inext, t, 0 end return args end return arguments e6be8dfccffa2057c3d50700f350d8d140c1dbf9 Шаблон:Join 10 32 74 2018-06-13T14:41:38Z wikipedia, ruwikipedia>Jack who built the house 0 перевод на модуль wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude> {{doc}} <!-- Категории — на подстраницу /doc, интервики — в Викиданные. --> </noinclude> 92bb17b5322d3ae0ceab93d4dad3d31810d47eb0 Шаблон:Скрытый 10 62 134 2018-06-14T09:27:38Z wikipedia, ruwikipedia>Iniquity 0 Iniquity переименовал страницу [[Шаблон:Скрытый]] в [[Шаблон:Скрытый блок]]: унификация названий, в схеме [[Википедия:Форум/Архив/Предложения/2018/01#Шаблоны,_скрывающие_содержимое]] wikitext text/x-wiki #перенаправление [[Шаблон:Скрытый блок]] 97cc939c1c8ece875b2ec360f85980bd6f1bbed7 Шаблон:Конец скрытого блока 10 46 102 2018-06-14T09:55:59Z wikipedia, ruwikipedia>Iniquity 0 общая документация wikitext text/x-wiki <includeonly></div></div></includeonly><noinclude> {{doc|Шаблон:Начало скрытого блока/doc}}</noinclude> 2da6ac8eb0812fb4183a70b516009d40920e281f Шаблон:Без начала 10 96 202 2018-07-11T22:30:39Z wikipedia, ruwikipedia>A particle for world to form 0 Для возможности использовать подстановку. wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#ifeq:{{<includeonly>safesubst:</includeonly>Str_left|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}*|{{{2}}}*|{{<includeonly>safesubst:</includeonly>Str_right|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}|{{{1}}}}}<noinclude>{{doc}}</noinclude> 9fbca6f1fc236cb17fe77d76891e3f9c2afa2117 Шаблон:Str rightc 10 49 108 2018-07-11T22:33:58Z wikipedia, ruwikipedia>A particle for world to form 0 Для возможности использовать подстановку. wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude> 0401d500dcc2224d44867ba0ea1f6c0fbeb758a0 Шаблон:Str left 10 31 72 2018-07-11T22:39:12Z wikipedia, ruwikipedia>A particle for world to form 0 Для возможности использовать подстановку. wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude> {{doc}} </noinclude> c1f57b63826f4d455dcaec8d2c24a2b8268f42ec Шаблон:Str sub 10 42 94 2018-09-29T20:45:02Z wikipedia, ruwikipedia>TenBaseT 0 категории в документации wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude> {{doc}} </noinclude> 3043790f8803e868cf6097b475fd58ba742887fe Шаблон:No-doc 10 38 86 2019-01-17T08:39:04Z wikipedia, ruwikipedia>Dima st bk 0 Защитил страницу [[Шаблон:No-doc]]: критический шаблон или модуль ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только администраторы] (бессрочно)) wikitext text/x-wiki {{#ifeq: {{SUBPAGENAME}} | doc || {{#if: {{#if: {{yesno|{{{nocat|}}}}} | x }}{{#switch: {{NAMESPACE}} | {{ns:10}} | {{ns:828}} = | x }} || {{{1|}}} }} }}<noinclude>{{doc}}</noinclude> da013ca5b5f97f94bee392ff3a4488046f2ceac7 Шаблон:Demo 10 102 214 2019-04-25T13:40:59Z wikipedia, ruwikipedia>QBA-bot 0 Защитил страницу [[Шаблон:Demo]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki {{#invoke:Demo|main}}<noinclude>{{documentation}}</noinclude> e458e378477c6077a01987f334fdc73bee48512c Модуль:Wikidata/count 828 95 200 2019-06-29T03:57:18Z wikipedia, ruwikipedia>Dima st bk 0 Изменил уровень защиты [[Модуль:Wikidata/count]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно)) Scribunto text/plain local p = {} function p.getCount( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; local claims; if options.property then -- TODO: Почему тут может не быть property? claims = context.selectClaims( options, options.property ); end if claims == nil then return ''; --TODO error? end return table.getn(claims); end function p.isMultiple( context, options ) local count = p.getCount( context, options ); local multiple = ''; if( count ~= nil and count ~= '' and count > 1 ) then multiple = 1; end return multiple; end return p 8ccf5dd7170a466674627b0afdf32c6bd2318154 Модуль:TableTools 828 11 32 2019-08-26T06:20:31Z wikipedia, ruwikipedia>Serhio Magpie 0 Обновлено с https://en.wikipedia.org/w/index.php?title=Module:TableTools&oldid=887403551 Scribunto text/plain --[[ ------------------------------------------------------------------------------------ -- TableTools -- -- -- -- This module includes a number of functions for dealing with Lua tables. -- -- It is a meta-module, meant to be called from other Lua modules, and should -- -- not be called directly from #invoke. -- ------------------------------------------------------------------------------------ --]] local libraryUtil = require('libraryUtil') local p = {} -- Define often-used variables and functions. local floor = math.floor local infinity = math.huge local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti --[[ ------------------------------------------------------------------------------------ -- isPositiveInteger -- -- This function returns true if the given value is a positive integer, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a given table key is in the array part or the -- hash part of a table. ------------------------------------------------------------------------------------ --]] function p.isPositiveInteger(v) if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- isNan -- -- This function returns true if the given number is a NaN value, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a value can be a valid table key. Lua will -- generate an error if a NaN is used as a table key. ------------------------------------------------------------------------------------ --]] function p.isNan(v) if type(v) == 'number' and tostring(v) == '-nan' then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- shallowClone -- -- This returns a clone of a table. The value returned is a new table, but all -- subtables and functions are shared. Metamethods are respected, but the returned -- table will have no metatable of its own. ------------------------------------------------------------------------------------ --]] function p.shallowClone(t) local ret = {} for k, v in pairs(t) do ret[k] = v end return ret end --[[ ------------------------------------------------------------------------------------ -- removeDuplicates -- -- This removes duplicate values from an array. Non-positive-integer keys are -- ignored. The earliest value is kept, and all subsequent duplicate values are -- removed, but otherwise the array order is unchanged. ------------------------------------------------------------------------------------ --]] function p.removeDuplicates(t) checkType('removeDuplicates', 1, t, 'table') local isNan = p.isNan local ret, exists = {}, {} for i, v in ipairs(t) do if isNan(v) then -- NaNs can't be table keys, and they are also unique, so we don't need to check existence. ret[#ret + 1] = v else if not exists[v] then ret[#ret + 1] = v exists[v] = true end end end return ret end --[[ ------------------------------------------------------------------------------------ -- numKeys -- -- This takes a table and returns an array containing the numbers of any numerical -- keys that have non-nil values, sorted in numerical order. ------------------------------------------------------------------------------------ --]] function p.numKeys(t) checkType('numKeys', 1, t, 'table') local isPositiveInteger = p.isPositiveInteger local nums = {} for k, v in pairs(t) do if isPositiveInteger(k) then nums[#nums + 1] = k end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- affixNums -- -- This takes a table and returns an array containing the numbers of keys with the -- specified prefix and suffix. For example, for the table -- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will -- return {1, 3, 6}. ------------------------------------------------------------------------------------ --]] function p.affixNums(t, prefix, suffix) checkType('affixNums', 1, t, 'table') checkType('affixNums', 2, prefix, 'string', true) checkType('affixNums', 3, suffix, 'string', true) local function cleanPattern(s) -- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally. s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1') return s end prefix = prefix or '' suffix = suffix or '' prefix = cleanPattern(prefix) suffix = cleanPattern(suffix) local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$' local nums = {} for k, v in pairs(t) do if type(k) == 'string' then local num = mw.ustring.match(k, pattern) if num then nums[#nums + 1] = tonumber(num) end end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- numData -- -- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table -- of subtables in the format -- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} } -- Keys that don't end with an integer are stored in a subtable named "other". -- The compress option compresses the table so that it can be iterated over with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.numData(t, compress) checkType('numData', 1, t, 'table') checkType('numData', 2, compress, 'boolean', true) local ret = {} for k, v in pairs(t) do local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$') if num then num = tonumber(num) local subtable = ret[num] or {} if prefix == '' then -- Positional parameters match the blank string; put them at the start of the subtable instead. prefix = 1 end subtable[prefix] = v ret[num] = subtable else local subtable = ret.other or {} subtable[k] = v ret.other = subtable end end if compress then local other = ret.other ret = p.compressSparseArray(ret) ret.other = other end return ret end --[[ ------------------------------------------------------------------------------------ -- compressSparseArray -- -- This takes an array with one or more nil values, and removes the nil values -- while preserving the order, so that the array can be safely traversed with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.compressSparseArray(t) checkType('compressSparseArray', 1, t, 'table') local ret = {} local nums = p.numKeys(t) for _, num in ipairs(nums) do ret[#ret + 1] = t[num] end return ret end --[[ ------------------------------------------------------------------------------------ -- sparseIpairs -- -- This is an iterator for sparse arrays. It can be used like ipairs, but can -- handle nil values. ------------------------------------------------------------------------------------ --]] function p.sparseIpairs(t) checkType('sparseIpairs', 1, t, 'table') local nums = p.numKeys(t) local i = 0 local lim = #nums return function () i = i + 1 if i <= lim then local key = nums[i] return key, t[key] else return nil, nil end end end --[[ ------------------------------------------------------------------------------------ -- size -- -- This returns the size of a key/value pair table. It will also work on arrays, -- but for arrays it is more efficient to use the # operator. ------------------------------------------------------------------------------------ --]] function p.size(t) checkType('size', 1, t, 'table') local i = 0 for k in pairs(t) do i = i + 1 end return i end local function defaultKeySort(item1, item2) -- "number" < "string", so numbers will be sorted before strings. local type1, type2 = type(item1), type(item2) if type1 ~= type2 then return type1 < type2 else -- This will fail with table, boolean, function. return item1 < item2 end end --[[ Returns a list of the keys in a table, sorted using either a default comparison function or a custom keySort function. ]] function p.keysToList(t, keySort, checked) if not checked then checkType('keysToList', 1, t, 'table') checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' }) end local list = {} local index = 1 for key, value in pairs(t) do list[index] = key index = index + 1 end if keySort ~= false then keySort = type(keySort) == 'function' and keySort or defaultKeySort table.sort(list, keySort) end return list end --[[ Iterates through a table, with the keys sorted using the keysToList function. If there are only numerical keys, sparseIpairs is probably more efficient. ]] function p.sortedPairs(t, keySort) checkType('sortedPairs', 1, t, 'table') checkType('sortedPairs', 2, keySort, 'function', true) local list = p.keysToList(t, keySort, true) local i = 0 return function() i = i + 1 local key = list[i] if key ~= nil then return key, t[key] else return nil, nil end end end --[[ Returns true if all keys in the table are consecutive integers starting at 1. --]] function p.isArray(t) checkType("isArray", 1, t, "table") local i = 0 for k, v in pairs(t) do i = i + 1 if t[i] == nil then return false end end return true end -- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 } function p.invert(array) checkType("invert", 1, array, "table") local map = {} for i, v in ipairs(array) do map[v] = i end return map end --[[ { "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true } --]] function p.listToSet(t) checkType("listToSet", 1, t, "table") local set = {} for _, item in ipairs(t) do set[item] = true end return set end --[[ Recursive deep copy function. Preserves identities of subtables. ]] local function _deepCopy(orig, includeMetatable, already_seen) -- Stores copies of tables indexed by the original table. already_seen = already_seen or {} local copy = already_seen[orig] if copy ~= nil then return copy end if type(orig) == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen) end already_seen[orig] = copy if includeMetatable then local mt = getmetatable(orig) if mt ~= nil then local mt_copy = deepcopy(mt, includeMetatable, already_seen) setmetatable(copy, mt_copy) already_seen[mt] = mt_copy end end else -- number, string, boolean, etc copy = orig end return copy end function p.deepCopy(orig, noMetatable, already_seen) checkType("deepCopy", 3, already_seen, "table", true) return _deepCopy(orig, not noMetatable, already_seen) end --[[ Concatenates all values in the table that are indexed by a number, in order. sparseConcat{ a, nil, c, d } => "acd" sparseConcat{ nil, b, c, d } => "bcd" ]] function p.sparseConcat(t, sep, i, j) local list = {} local list_i = 0 for _, v in p.sparseIpairs(t) do list_i = list_i + 1 list[list_i] = v end return table.concat(list, sep, i, j) end --[[ -- This returns the length of a table, or the first integer key n counting from -- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return -- a different value when there are gaps in the array portion of the table. -- Intended to be used on data loaded with mw.loadData. For other tables, use #. -- Note: #frame.args in frame object always be set to 0, regardless of -- the number of unnamed template parameters, so use this function for -- frame.args. --]] function p.length(t) local i = 1 while t[i] ~= nil do i = i + 1 end return i - 1 end function p.inArray(arr, valueToFind) checkType("inArray", 1, arr, "table") -- if valueToFind is nil, error? for _, v in ipairs(arr) do if v == valueToFind then return true end end return false end return p fe918509f168332267834b3a6f5c219a9de5b2e7 Шаблон:Br separated entries 10 90 190 2019-08-30T23:08:35Z wikipedia, ruwikipedia>Ле Лой 0 Защитил страницу [[Шаблон:Br separated entries]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно)) wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude> {{doc}} </noinclude> 2113c3c6e95a84235b9f7a85e7ea17208e8f91df Шаблон:T 10 40 90 2019-10-20T16:35:32Z wikipedia, ruwikipedia>Helgo13 0 Helgo13 переименовал страницу [[Шаблон:T]] в [[Шаблон:Tl]] wikitext text/x-wiki #перенаправление [[Шаблон:Tl]] c0a76efe437d8a513d9f6878297f399a23944abd Шаблон:Tl 10 41 92 2019-10-20T16:35:32Z wikipedia, ruwikipedia>Helgo13 0 Helgo13 переименовал страницу [[Шаблон:T]] в [[Шаблон:Tl]] wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude> 61fe4d068895a5e7e5802767f5d7df71a7561c57 Шаблон:Карточка/внизу 10 26 62 2019-11-13T23:18:52Z wikipedia, ruwikipedia>Serhio Magpie 0 Перенесено в общие стили wikitext text/x-wiki <includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude> {{doc}} </noinclude> 169fb2d10b0847c2fd677eda9f159ba99025198f Шаблон:If-wikidata 10 87 184 2019-11-13T23:40:02Z wikipedia, ruwikipedia>Serhio Magpie 0 + from wikitext text/x-wiki {{#switch:{{wikidata|{{{1|}}}|{{{2|}}}|plain={{{plain|true}}}|from={{{from|}}}|somevalue={{{somevalue|}}}|novalue={{{novalue|}}}}}|значение отсутствует|={{{4|}}}|#default={{{3}}}}}<noinclude> {{doc}} </noinclude> a8a37fd2c4f1a266ec48783d7d0ad22cdcd812cb Шаблон:Карточка/официальное название 10 97 204 2020-02-29T12:06:43Z wikipedia, ruwikipedia>Helgo13 0 Защитил страницу [[Шаблон:Карточка/официальное название]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно)) wikitext text/x-wiki {{wikidata|p1448[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<noinclude>{{doc}}</noinclude> 708a700c58a199343531d8fb3eec7ee897e92732 Модуль:Separated entries 828 39 88 2020-07-05T06:33:20Z wikipedia, ruwikipedia>Serhio Magpie 0 + newline Scribunto text/plain -- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (convert to Unicode) HTML escape sequences, such as "&#32;" for space. and mw.text.decode(args.separator) or '' local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator -- Discard named parameters. local values = compressSparseArray(args) return mw.text.listToText(values, separator, conjunction) end local function makeInvokeFunction(separator, conjunction) return function (frame) local args = require('Module:Arguments').getArgs(frame) args.separator = separator or args.separator args.conjunction = conjunction or args.conjunction return p._main(args) end end p.main = makeInvokeFunction() p.br = makeInvokeFunction('<br />') p.newline = makeInvokeFunction('\n') p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain()) return p 33a68f0a46d62c42b6523a548f0f881e82ecfe58 Шаблон:Wikidata number switch 10 79 168 2020-07-12T09:21:12Z wikipedia, ruwikipedia>Serhio Magpie 0 Проверка - если ничего нет из первых трёх параметров, ничего и не выводить wikitext text/x-wiki {{#if: {{{3|}}} | {{#if: {{{5|}}} | {{{5|}}} | {{{3|}}} }} | {{#if: {{{2|}}} | {{#if: {{{4|}}} | {{{4|}}} | {{{2|}}} }} | {{#if: {{{1|}}} | {{#if: {{{4|}}}{{{5|}}} | {{#if: {{wikidata|{{{1|}}}|property-module=Wikidata/count|property-function=isMultiple|from={{{from|}}}}} | {{{5|}}} | {{{4|}}} }} | {{wikidata|{{{1|}}}|from={{{from|}}}}} }} }} }} }}<noinclude> {{doc}} </noinclude> 7541bb47e73905a8ee240baa1dab1801f9f7b166 Шаблон:Карточка/блок 10 92 194 2020-10-20T13:56:13Z wikipedia, ruwikipedia>Wikisaurus 0 Wikisaurus переименовал страницу [[Шаблон:Фрагмент таблицы]] в [[Шаблон:Карточка/блок]]: унификация с другими шаблонами для создания частей карточки wikitext text/x-wiki <includeonly>{{#invoke:Infobox|renderLines}}</includeonly><noinclude>{{doc}}</noinclude> b76f4bc95a8a44fea1fa0f577d84111b51ce1385 Модуль:Transclude 828 29 68 2020-11-17T12:38:34Z wikipedia, ruwikipedia>Wikisaurus 0 пропускать пустые параметры в forall и join Scribunto text/plain local p={} -- Вызывает внутренний шаблон с аргументами объемлющего шаблона function p.call(frame) local template = frame.args[1] local args = frame:getParent().args return frame:expandTemplate{ title=template, args=args } end -- Общая реализация для forall и call local function forallImpl(args, separator, conjunction, func) -- нумерованные ключи из args local keys = {} -- перебор в произвольном порядке, даже для нумерованных ключей for key, value in pairs(args) do if type(key) == 'number' and value and value ~= '' then table.insert(keys, key) end end table.sort(keys) local results = {} for _, key in ipairs(keys) do local value = func(args[key]) table.insert(results, value) end return mw.text.listToText(results, separator, conjunction) end -- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному function p.forall(frame) local template = frame.args[1] local separator = frame.args.separator or '' local conjunction = frame.args.conjunction or separator local args = frame:getParent().args local func = function(value) return frame:expandTemplate{ title = template, args = {value} } -- или другой frame? end return forallImpl(args, separator, conjunction, func) end -- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку function p.join(frame) local separator = frame.args[1] or '' local conjunction = frame.args[2] or separator local args = frame:getParent().args local func = function(value) return value end return forallImpl(args, separator, conjunction, func) end -- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами local function deleteDuplicates(args) local res = {} for key, value in pairs(args) do if args[key+1] ~= value then table.insert(res, value) end end return res end -- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона function p.npc(frame) local args = frame:getParent().args local templateFrame = frame:getParent() local template = frame.args[1] -- определение, блоки аргументов с какими номерами нужны: -- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок local nums = {} for key, _ in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- учитывать "параметр12", только если задано "параметр" if num and frame.args[main] then table.insert(nums, num) end end table.sort(nums) nums = deleteDuplicates(nums) -- проходить по нужным номерам блоков по возрастанию и однократно -- подставлять в шаблон: -- 1. общие аргументы данного модуля -- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок local results = {} for _, blockNum in ipairs(nums) do -- общие аргументы модуля, которые передаются в каждый блок local blockArgs = mw.clone(frame.args) -- metatable ломает expandTemplate setmetatable(blockArgs, nil) for key, value in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля if blockNum == num and frame.args[main] then blockArgs[main] = value end end local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs } table.insert(results, blockText) end return table.concat(results) end -- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2]. function p.cycle(f) local tf,ac,op=f:getParent(), {}, f.args.output or 'inline'; local sep=''; if op == 'newline' then sep='\n'; end for p,k in pairs(f.args) do if type(p)=='number' then if p>2 then ac[p-1]=k end else ac[p]=k end end local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1, f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or ''; fh=tonumber(fh) or fh:match('^%s*(.-)%s*$'); s=tonumber(s); local acr={}; if not s then error('Начало цикла «'..s..'» — не число') end local function dc(order) local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} } if order == 'desc' then s=s-1; else s=s+1; end if r~='' then table.insert(acr,r); return r end end if type(fh)=='number' then if fh > s then while s<=fh do dc('asc') end else while s>=fh do dc('desc') end end elseif fh~='' then while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end else while dc('asc') do end end return table.concat(acr, sep) end return p c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59 Модуль:Hash 828 50 110 2021-02-07T10:01:11Z wikipedia, ruwikipedia>Grain of sand 0 + list() для вывода списка доступных алгоритмов Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local p = {} local function inTable(table, value) for k, v in pairs(table) do if v == value then return true end end return false end function p.list(frame) return table.concat(mw.hash.listAlgorithms(), '; ') end function p.main(frame) local args = getArgs(frame, { frameOnly = true }) local algorithm if not args[1] then return '<span class="error">Не указана строка для хеширования.</span>' end if args[2] then if not inTable(mw.hash.listAlgorithms(), args[2]) then return '<span class="error">Алгоритм хеширования ' .. args[2] .. ' не поддерживается, или вы неточно указали его имя. Используйте функцию <kbd>mw.hash.listAlgorithms()</kbd> для получения списка доступных алгоритмов.</span>' end algorithm = args[2] else -- Алгоритм выбран из соображений быстродействия (см. [[:en:Fowler–Noll–Vo hash function]]), -- 64-битная функция используется для уменьшения вероятности коллизий до пренебрежимо малой -- величины. Возможно, есть лучшая опция — проверяйте. algorithm = 'fnv164' end return mw.hash.hashValue(algorithm, args[1]) end return p 5d18513e574435f191164695449a620b031f93ec Шаблон:Doc/end 10 58 126 2021-02-14T18:18:13Z wikipedia, ruwikipedia>Putnik 0 для модулей предзагрузка нормально не работает wikitext text/x-wiki <includeonly></div> </div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] --> | {{^|1em}} | <div class="ts-doc-footer plainlinks"> {{#ifeq: {{str left|{{PAGENAME}}|9}} | Песочница | | {{#ifeq: {{str rightc|{{PAGENAME}}|10}} | /песочница | | Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}} | Модуль | модуль | шаблон }}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }} | {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }} }})</small> или {{#ifeq: {{NAMESPACE}} | Модуль | [[Модуль:Песочница|песочнице для модулей]] | своём [[ВП:ЛП|личном пространстве]] }}.<br> }} }}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]].&#32;}}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]. </div> }}</includeonly><noinclude>{{doc}}</noinclude> 758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e Шаблон:Tnav 10 65 140 2021-02-28T17:42:07Z wikipedia, ruwikipedia>Jack who built the house 0 дополнение wikitext text/x-wiki {{t|{{{1|}}}|nav|comment={{{comment|}}}}}<noinclude> {{doc-inline}} Это — обёртка для шаблона {{t|tl}}, предназначенная для использования в блоках навигации. Она передаёт в него флаг <code>nav</code> и комментарий в параметре {{para|comment}}. {{шаблоны для документирования}} {{doc-end}} [[Категория:Шаблоны:Ссылки на шаблоны]] [[Категория:Шаблоны:Для навигационных шаблонов]] </noinclude> 583d607aa213790ae32dda4018a413255493e42b Модуль:Color contrast 828 34 78 2021-03-01T22:40:23Z wikipedia, ruwikipedia>Grain of sand 0 local Scribunto text/plain -- -- This module implements -- {{Color contrast ratio}} -- {{Greater color contrast ratio}} -- {{ColorToLum}} -- {{RGBColorToLum}} -- local p = {} local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' ) local function sRGB ( v ) if (v <= 0.03928) then v = v / 12.92 else v = math.pow((v+0.055)/1.055, 2.4) end return v end local function rgbdec2lum( R, G, B ) if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255) else return '' end end local function hsl2lum( h, s, l ) if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then local c = (1 - math.abs(2*l - 1))*s local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) ) local m = l - c/2 local r, g, b = m, m, m if( 0 <= h and h < 60 ) then r = r + c g = g + x elseif( 60 <= h and h < 120 ) then r = r + x g = g + c elseif( 120 <= h and h < 180 ) then g = g + c b = b + x elseif( 180 <= h and h < 240 ) then g = g + x b = b + c elseif( 240 <= h and h < 300 ) then r = r + x b = b + c elseif( 300 <= h and h < 360 ) then r = r + c b = b + x end return rgbdec2lum(255*r, 255*g, 255*b) else return '' end end local function color2lum( c ) if (c == nil) then return '' end -- whitespace c = c:match( '^%s*(.-)[%s;]*$' ) -- lowercase c = c:lower() -- first try to look it up local L = HTMLcolor[c] if (L ~= nil) then return L end -- convert from hsl if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100) end -- convert from rgb if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$') return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B)) end -- convert from rgb percent if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100) end -- remove leading # (if there is one) and whitespace c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$') -- split into rgb local cs = mw.text.split(c or '', '') if( #cs == 6 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]) local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]) local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]) return rgbdec2lum(R, G, B) elseif ( #cs == 3 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1]) local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2]) local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3]) return rgbdec2lum(R, G, B) end -- failure, return blank return '' end function p._greatercontrast(args) local bias = tonumber(args['bias'] or '0') or 0 local v1 = color2lum(args[1] or '') local c2 = args[2] or '#FFFFFF' local v2 = color2lum(c2) local c3 = args[3] or '#000000' local v3 = color2lum(c3) local ratio1 = 0; local ratio2 = 0; if (type(v1) == 'number' and type(v2) == 'number') then ratio1 = (v2 + 0.05)/(v1 + 0.05) ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1 end if (type(v1) == 'number' and type(v3) == 'number') then ratio2 = (v3 + 0.05)/(v1 + 0.05) ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2 end return (ratio1 + bias > ratio2) and c2 or c3 end function p._ratio(args) local v1 = color2lum(mw.text.unstripNoWiki(args[1] or '')) local v2 = color2lum(mw.text.unstripNoWiki(args[2] or '')) if (type(v1) == 'number' and type(v2) == 'number') then -- v1 should be the brighter of the two. if v2 > v1 then v1, v2 = v2, v1 end return (v1 + 0.05)/(v2 + 0.05) else return args['error'] or '?' end end function p._styleratio(args) local style = (args[1] or ''):lower() local bg, fg = 'white', '#202122' local lum_bg, lum_fg = 1, 0.016 if args[2] then local lum = color2lum(args[2]) if lum ~= '' then bg, lum_bg = args[2], lum end end if args[3] then local lum = color2lum(args[3]) if lum ~= '' then fg, lum_fg = args[3], lum end end local slist = mw.text.split(style or '', ';') for k = 1, #slist do local s = slist[k] local k, v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' ) k = k or '' v = v or '' if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_bg = v, lum end elseif (k:match('^[%s]*(color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_fg = v, lum end end end if lum_bg > lum_fg then return (lum_bg + 0.05)/(lum_fg + 0.05) else return (lum_fg + 0.05)/(lum_bg + 0.05) end end function p.lum(frame) return color2lum(frame.args[1] or frame:getParent().args[1]) end function p.ratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._ratio(args) end function p.styleratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._styleratio(args) end function p.greatercontrast(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._greatercontrast(args) end return p cce580326bee8eaf3c81df6c76c04a9a2909dfa2 Шаблон:Wikidata 10 78 166 2021-04-01T12:24:50Z wikipedia, ruwikipedia>MBH 0 [[ВП:Откат|откат]] правок [[Special:Contribs/Lê Lợi (bot)|Lê Lợi (bot)]] ([[UT:Lê Lợi (bot)|обс.]]) к версии Wikisaurus wikitext text/x-wiki <includeonly>{{#invoke:Wikidata|formatProperty|property={{{1|}}}|value={{{2|}}}}}</includeonly><noinclude>{{doc}}</noinclude> 9d3d422eca39504b018df6ec0bb047392a7aba7e Модуль:Infobox 828 28 66 2021-08-16T20:12:46Z wikipedia, ruwikipedia>Putnik 0 scope="colgroup" для заголовков Scribunto text/plain local p = {}; local yesno = require('Module:Yesno') local function _renderLine( frame, args, i ) if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then return '' elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' ); local class = ( args[ 'класс' .. i ] or '' ); return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' .. args[ 'заголовок' .. i ] .. '</th>\n</tr>'; end if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then return args[ 'блок' .. i ]; end local text = args[ 'текст' .. i ] or ''; if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then text = frame:expandTemplate{ title = 'Wikidata', args = { args[ 'викиданные' .. i ], text, from = args[ 'from' ] or '' } }; end if text ~= '' then local label = args[ 'метка' .. i ] or ''; local class = args[ 'класс' .. i ] or ''; if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then class = class .. ' plainlist'; end if class ~= '' then class = ' class="' .. class .. '"'; end local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' ); if label == '' then style = 'text-align:center;' .. style; end if style ~= '' then style = ' style="' .. style .. '"'; end if label ~= '' then local labelClass = args[ 'класс_меток' ] or ''; if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then labelClass = labelClass .. ' plainlist'; end if labelClass ~= '' then labelClass = ' class="' .. labelClass .. '"'; end local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' ); if labelStyle ~= '' then labelStyle = ' style="' .. labelStyle .. '"'; end return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' .. '\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return ''; end local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.renderLine( frame ) local args = frame:getParent().args; return _renderLine(frame, args, '') end function p.renderLines( frame ) local args = frame:getParent().args; local res = '' local header, text = '', '' local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false) for i = 1, maxNumber(args) do if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then if text ~= '' or not autoHeaders then res = res .. header .. text end header, text = _renderLine(frame, args, i), '' else text = text .. _renderLine(frame, args, i) end end if text ~= '' or not autoHeaders then res = res .. header .. text end return res end return p; c830c997bd3d15923f347277e3b0ae71b7ba917e Шаблон:Карточка/блок с маркерами 10 91 192 2021-10-24T15:48:39Z wikipedia, ruwikipedia>Oleg Yunakov 0 Защитил страницу [[Шаблон:Карточка/блок с маркерами]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki {{#invoke:Infobox/bulleted block|main}}<noinclude>{{doc}}</noinclude> 71e7755aa4fb1e445f008da13d6fa4212aea3c38 Шаблон:Ombox 10 59 128 2021-10-24T18:05:30Z wikipedia, ruwikipedia>Oleg Yunakov 0 Изменил настройки защиты для «[[Шаблон:Ombox]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki {{#invoke:Message box|ombox}}<noinclude> {{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude> ab34435c5ebc29de589c9b059e88da5d0e6f16e4 Модуль:Infobox/bulleted block 828 93 196 2021-10-24T18:17:22Z wikipedia, ruwikipedia>Oleg Yunakov 0 Защитил страницу [[Модуль:Infobox/bulleted block]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) Scribunto text/plain local p = {} -- takes strings or nils; returns a string function makeText(frame, text, wikidata, from) if wikidata and wikidata ~= ''then return frame:expandTemplate{title='Wikidata', args={wikidata, text or '', from=from or ''}} else return text or '' end end -- from [[ru:Модуль:Infobox]] local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.main(frame) local args = frame:getParent().args local maxNumberArgs = maxNumber(args) local texts = {} for i = 1, maxNumberArgs do if args['текст' .. i] then texts[i] = makeText(frame, args['текст' .. i], args['викиданные' .. i], args['from']) end end local textsAreEmpty = true for i = 1, maxNumberArgs do if texts[i] and texts[i] ~= '' then textsAreEmpty = false end end local results = {} if not textsAreEmpty and args['подзаголовок'] and args['подзаголовок'] ~= '' then results['текст1'] = args['подзаголовок'] results['стиль_текста1'] = 'padding-bottom:0; border-bottom:0; text-align:left; font-weight:bold;' end local mainText = makeText(frame, args['текст'], args['викиданные'], args['from']) if mainText == '' and args['метка'] and args['метка'] ~= '' and not textsAreEmpty then mainText = '&nbsp;' end if mainText and mainText ~= '' then results['метка2'] = args['метка'] results['стиль_метки2'] = 'padding-bottom:0; border-bottom:0;' results['текст2'] = mainText results['стиль_текста2'] = 'padding-bottom:0; border-bottom:0;' end for i = 1, maxNumberArgs do if texts[i] and texts[i] ~= '' then results['метка' .. (i+2)] = '&nbsp;•&nbsp;' .. (args['метка' .. i] or '') results['текст' .. (i+2)] = texts[i] local last = true for j = i+1, maxNumberArgs do if texts[j] and texts[j] ~= '' then last = false end end if last then results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-top:0; border-top:0;' results['стиль_текста' .. (i+2)] = 'padding-top:0; border-top:0;' else results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;' results['стиль_текста' .. (i+2)] = 'padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;' end end end return frame:expandTemplate{title='Карточка/блок', args=results} end return p 856b97606e1f2809c940e384f6fe71a575ca019e Шаблон:Tlp 10 52 114 2021-10-24T18:18:30Z wikipedia, ruwikipedia>Oleg Yunakov 0 Изменил настройки защиты для «[[Шаблон:Tlp]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude> 36c309cb28ccf0901f4fff46cbd35cdabcf00661 Модуль:Template call code 828 12 34 2021-10-26T19:03:06Z wikipedia, ruwikipedia>Jack who built the house 0 -избыточный код Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local ru = mw.language.new('ru') local p = {} -- Используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k, v in pairs(other) do res[k] = v end return res end local function makeInvokeFunc(funcName, flags) return function (frame) local args = copy(getArgs(frame, { trim = false, removeBlanks = false })) return p[funcName](args, flags) end end --предотвращает обработку вики-текста в отображении образца local function processText(str, nowiki) local res = str if nowiki then str = mw.text.unstripNoWiki(str) str = string.gsub(str, '%[', '&#91;') str = string.gsub(str, '%]', '&#93;') str = string.gsub(str, '<', '&lt;') str = string.gsub(str, '>', '&gt;') str = string.gsub(str, '{', '&#123;') str = string.gsub(str, '|', '&#124;') str = string.gsub(str, '}', '&#125;') str = string.gsub(str, '\'', '&#39;') str = string.gsub(str, '"', '&quot;') str = string.gsub(str, '(://)', '<span>%1</span>') end return str end local function addParams(args, params) local text, equals_pos, param, value = '', 0, '', '' local function addPipe() if params.spaced then text = text .. ' ' end text = text .. '<span class="' if not params.spaced then text = text .. ' ts-templateCallCode-pipe' end if not params.black then text = text .. ' ts-templateCallCode-weak' end -- &#124;, чтобы не трактовалось как разделитель ячеек в таблицах text = text .. '">&#124;</span>' end local beforeParam = '<span class="ts-templateCallCode-param">' local afterParam = '</span>' for k, v in pairs(args) do if type(k) == 'number' then -- Неименованные параметры if k >= params.from then equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos - 2 then equals_pos = nil end if equals_pos then -- Содержащие «=» преобразуем в именованные param = v:sub(1, equals_pos - 1) value = v:sub(equals_pos + 1) addPipe() text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam else -- Истинно неименованные addPipe() local paramValue = processText(v, params.nowiki) if #paramValue ~= 0 then text = text .. beforeParam .. paramValue .. afterParam end end end elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида addPipe() text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam end end return text end function p._main(args, flags) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local optpText if not flags.withoutParams then if name then local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp if spanOffset then optpText = mw.ustring.sub(name, spanOffset) name = mw.ustring.sub(name, 1, spanOffset - 1) end end end local yesno = require('Module:Yesno') local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr local tag, style, comment, lang, sister, global, textInPlaceOfName, namePrefix, prefix, postfix, nowiki local spaced, from if flags.withoutParams then for i, v in ipairs(args) do if v == 'nl' or v == 'nolink' then noLink = true elseif v == 's' then subst = true elseif v == 'п' then podst = true elseif v == 'g' then global = true elseif v == 'nav' then nav = true elseif v == 'noredir' then noRedirect = true elseif v == 'u' then ucFirst = true elseif v == 'b' then black = true elseif v == 'nobr' then nobr = true end end tag = args.tag or 'span' style = args.style comment = args.comment lang = args.lang sister = args.sister textInPlaceOfName = args.text namePrefix = args.nameprefix prefix = args.prefix postfix = args.postfix nowiki = args.nowiki else noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) subst = yesno(args._s, false) podst = yesno(args['_п'], false) global = yesno(args._g, false) nav = yesno(args._nav, false) noRedirect = yesno(args._noredir, false) ucFirst = yesno(args._u, false) black = yesno(args._b, false) nobr = yesno(args._nobr, false) tag = args._tag or 'span' style = args._style comment = args._comment lang = args._lang sister = args._sister textInPlaceOfName = args._text namePrefix = args._nameprefix prefix = args._prefix postfix = args._postfix nowiki = args._nowiki spaced = yesno(args._spaced, false) from = (tonumber(args._from) or 2) - 1 end global = global or name and mw.ustring.sub(name, 1, 1) == ':' black = black or tag ~= 'span' if textInPlaceOfName == '' then textInPlaceOfName = nil end if comment == '' then comment = nil end if lang == '' then lang = nil end if sister == '' then sister = nil end if namePrefix == '' then namePrefix = nil end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then podst = true name = mw.ustring.sub(trimmedName, 7) end end if subst then namePrefix = 'subst:' elseif podst then namePrefix = 'подст:' end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not ucFirst and ( ( ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if lang then table.insert(prefixes, lang) end if sister then table.insert(prefixes, sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = noLink or currentTitle == titleObject if not noLink then if not noRedirect or ( noRedirect and not lang and not sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if tag then text = text .. '<' .. tag .. ' class="ts-templateCallCode' if nobr then text = text .. ' nowrap' end text = text .. '"' if style then text = text .. ' style="' .. style .. '"' end text = text .. '>' end if prefix then text = text .. processText(prefix, nowiki) end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-opening' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">{{' if namePrefix then text = text .. namePrefix end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">' local commentedLabel if comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}}) commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (textInPlaceOfName or name) .. '</span>' end local label = (commentedLabel or textInPlaceOfName or name) if not noLink then if noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd if noRedirect then text = text .. '</span>' end else text = text .. label end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end if not flags.withoutParams then if optpText then text = text .. optpText end text = text .. addParams(args, { spaced = spaced, black = black, nowiki = nowiki, from = from }) if spaced then text = text .. ' ' end end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-closing' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">}}</span>' if postfix then text = text .. processText(postfix, nowiki) end if tag then text = text .. '</' .. tag .. '>' end local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } } return ts .. text end function p._onlyParams(args) local yesno = require('Module:Yesno') return addParams(args, { spaced = yesno(args._spaced, false), black = true, nowiki = yesno(args._nowiki, false), from = 1 }) end p.withoutParams = makeInvokeFunc('_main', {withoutParams = true}) p.withParams = makeInvokeFunc('_main', {withoutParams = false}) p.onlyParams = makeInvokeFunc('_onlyParams') return p c4cde66869b509219e9bf629a766ce30ad0bdf97 Шаблон:Ifempty 10 45 100 2021-11-07T14:03:01Z wikipedia, ruwikipedia>Grain of sand 0 на модуль wikitext text/x-wiki <includeonly>{{#invoke:Ifempty|main}}</includeonly><noinclude> {{Doc}} <!-- Add categories and interwikis to the /doc subpage, not here! Добавляйте категории и интервики на подстраницу документации, а не сюда --> </noinclude> c14bef2160201468f96da309e565ff2fde725cf5 Модуль:Ifempty 828 48 106 2021-11-08T15:29:31Z wikipedia, ruwikipedia>Ping08 0 Изменил настройки защиты для «[[Модуль:Ifempty]]»: критический шаблон или модуль: более 125000 включений ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) Scribunto text/plain local p = {} local getArgs = require('Module:Arguments').getArgs function p.main(frame) local args = getArgs(frame, {removeBlanks = false}) local before = args['до'] local after = args['после'] for i, v in ipairs(args) do if v ~= '' then return (before or '') .. v .. (after or '') end end end return p 875e8c9f03fb4cc02d80271ad3aaab13a9bcea86 Модуль:Template call code/styles.css 828 14 38 2021-11-15T10:35:51Z wikipedia, ruwikipedia>Jack who built the house 0 поддержка [[t:optp]] (например, на [[Модуль:Unsubst/doc]]) text text/plain .ts-templateCallCode-weak { color: #72777d; } .ts-templateCallCode-pipe { margin: 0 2px; } .ts-templateCallCode-pipe + .ts-templateCallCode-pipe, /* Template:Optp */ .ts-templateCallCode-pipe + .ts-templateCallCode-param > .ts-templateCallCode-weak:first-child > .ts-templateCallCode-pipe:first-child { margin-left: 0; } .ts-templateCallCode-param + .ts-templateCallCode-closing { margin-left: 2px; } span.ts-templateCallCode > .ts-templateCallCode-templateName a { /* Решение из https://ru.wikipedia.org/wiki/Шаблон:Фиттс */ padding: 0 0.5em !important; /* Перезаписываем стиль для .plainlinks a.external */ position: relative; margin: -0.5em; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ b3ed166240cf28c48a58b8d992794b753b2c6ef5 Шаблон:Карточка 10 8 26 2022-04-03T23:49:38Z wikipedia, ruwikipedia>Putnik 0 пробуем красить каждую карточку на странице отдельно, без перекрытия стилей; надеюсь, комбинация имя+вверху0+вверху+вверху2 достаточно уникальна и не вызовет ошибок wikitext text/x-wiki {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||{{#if:{{{цвет|}}}|{{#tag:templatestyles| |wrapper=.infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} |src=Шаблон:Цвет/{{{цвет|}}}.css }}}}}}}}<table class="infobox infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}} {{#if:{{{from|}}}|{{#ifeq:{{{from|}}}|-||data-from="{{{from}}}"}}}}><!-- Вверху0 -->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!-- Вверху -->{{#if:{{{вверху|}}}|<tr><th colspan="2" scope="colgroup" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!-- Вверху2 -->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!-- Вверху3 -->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!-- Изображение -->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}| <div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!-- Изображение2 -->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}| <div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!-- Изображение3 -->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}| <div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!-- Строки -->{{#invoke:Infobox|renderLines}}<!-- Внизу -->{{Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| класс_внизу={{{класс_внизу|}}}| внизу={{{внизу|}}}}}<!-- Внизу N -->{{#invoke:Transclude|npc|Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| стиль_внизу=| класс_внизу=| внизу=}} </table><includeonly><!-- статьи -->{{#if:{{NAMESPACE}}||<!-- -->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->}}<!-- шаблоны -->{{#ifeq:{{NAMESPACENUMBER}}|10|<!-- -->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{PAGENAME}}|<!-- -->[[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]<!-- -->{{#if:{{{стиль_тела|}}}{{{стиль_вверху|}}}{{{стиль_заголовков|}}}{{{стиль_внизу|}}}|[[Категория:Википедия:Шаблоны-карточки с явным указанием стилей]]}}<!-- -->}}<!-- -->}}<!-- любое пространство имён -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Википедия:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Википедия:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}</noinclude> 5bd0cadc0cad51dc109de7db63622ab36743d386 Шаблон:Карточка/Викисклад 10 80 170 2022-04-30T14:39:04Z wikipedia, ruwikipedia>ShinePhantom 0 еще одна проверочная категория для зачистки wikitext text/x-wiki {{wikidata|p373|{{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}}|plain=false|text=Медиафайлы на Викискладе|icon={{{icon|}}}|icon_size={{{icon_size|}}}|from={{{from|}}}}}<!-- -->{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#if: {{{1|}}} | [[Категория:Википедия:Ссылка на Викисклад непосредственно в статье]]<!-- -->{{#if: {{wikidata|p373|plain=true}} | {{#ifeq: {{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}} | {{wikidata|p373|plain=true}} |[[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных совпадают]]| [[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных отличаются]] }} | [[Категория:Википедия:Ссылка на Викисклад в статье, но не на Викиданных]] }} }}<!-- --> }}<!-- -->{{#ifeq: {{NAMESPACE}} | Шаблон | {{#if: {{{2|}}} | [[Категория:Википедия:Шаблоны для низа карточек с лишним параметром]] }} }}<!-- --><noinclude> {{doc}} </noinclude> 40ef9a463c772ddbf54feae9e21d4037b692253e Модуль:WikidataSelectors 828 84 178 2023-05-09T18:46:16Z wikipedia, ruwikipedia>Putnik 0 исправление метода load() Scribunto text/plain local i18n = { ["errors"] = { ["rank-not-valid"] = "Некорретное значение приоритета (rank)", ["cant-parse-condition"] = "Не удалось разобрать условие" } } local validRanks = { 'best', 'preferred', 'normal', 'deprecated' } --[[ Internal function for error message Input: key in errors table Output: error message ]] local function throwError( key ) error( i18n.errors[key] ) end local p = {} --[[ Load property and filter statements Input: entityId, selector string Output: filtered statements table ]] function p.load( entityId, propertySelector ) local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' ) if not propertyId then return nil end propertyId = string.upper( propertyId ) local allStatements = {} allStatements[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId ) return p.filter( allStatements, propertySelector ) end --[[ Parse selectors and filter statements Input: statements table, selector string Output: filtered statements table ]] function p.filter( allClaims, propertySelector ) propertySelector = mw.text.trim( propertySelector ) -- Get property ID from selector local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' ) if not propertyId then propertyId = '' end local initPos = #propertyId + 1 propertyId = string.upper( propertyId ) if ( not allClaims ) then return nil end local allPropertyClaims = allClaims[propertyId] if ( not allPropertyClaims ) then return nil end -- Gathering rules local rules = p.matchSelectors( propertySelector, initPos ) -- If there is no rank filter, than default rank is 'best' local isRanked = false for i, subRules in ipairs( rules ) do for j, rule in ipairs( subRules ) do if rule['type'] == 'rank' then isRanked = true break end end end if not isRanked then table.insert( rules, 1, { { type = 'rank', value = 'best' } } ) end -- Execute rules allPropertyClaims = p.applyRules( allPropertyClaims, rules ) return allPropertyClaims end --[[ Match and gather selector rules Input: string with selectors rules, start position Output: rules table ]] function p.matchSelectors( selectorsString, initPos ) local rules = {} local rawRulePattern = '^%s*%[%s*[^%[%]]+%s*%]%s*' local rulePattern = '^%s*%[%s*([^%[%]]+)%s*%]%s*$' if not initPos then initPos = 1 end local rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos ) while rawRule do initPos = initPos + #rawRule rule = mw.ustring.match( rawRule, rulePattern ) rule = mw.text.trim( rule ) local subRules = mw.text.split( rule, '%s*,%s*' ) local commands = {} local comm for i, subRule in ipairs( subRules ) do local isInversed = false if mw.ustring.match( subRule, '^!' ) then isInversed = true subRule = mw.ustring.match( subRule, '^!%s*(.+)$' ) end -- p123[1] if mw.ustring.match( subRule, '^%d+$' ) then table.insert( commands, { type = 'position', value = subRule, inversed = isInversed } ) -- p123[rank:preferred] elseif mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) then rank = mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) table.insert( commands, { type = 'rank', value = rank, inversed = isInversed } ) -- p123[language:xx] elseif mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) then value = mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) table.insert( commands, { type = 'language', value = value, inversed = isInversed } ) -- p123[language!:xx] elseif mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) then value = mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) table.insert( commands, { type = 'language', value = value, inversed = not isInversed } ) -- p123[min] elseif mw.ustring.match( subRule, '^min$' ) then table.insert( commands, { type = 'value_min' } ) -- p123[max] elseif mw.ustring.match( subRule, '^max$' ) then table.insert( commands, { type = 'value_max' } ) -- p123[min:p456] elseif mw.ustring.match( subRule, '^min%s*:%s*[Pp]%d+$' ) then value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' ) table.insert( commands, { type = 'qualifier_min', qualifier = value } ) -- p123[max:p456] elseif mw.ustring.match( subRule, '^max%s*:%s*[Pp]%d+$' ) then value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' ) table.insert( commands, { type = 'qualifier_max', qualifier = value } ) -- p123[unit:q789] elseif mw.ustring.match( subRule, '^unit%s*:%s*[^%[%],:]+$' ) then value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'unit', value = value, inversed = isInversed } ) -- p123[unit!:q789] elseif mw.ustring.match( subRule, '^unit%s*!:%s*[^%[%],:]+$' ) then value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'unit', value = value, inversed = not isInversed } ) -- p123[p456] elseif mw.ustring.match( subRule, '^[Pp]%d+$' ) then qualifier = mw.ustring.match( subRule, '^[Pp]%d+' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = nil, inversed = isInversed } ) -- p123[p456:q789] elseif mw.ustring.match( subRule, '^[Pp]%d+%s*:%s*[^%[%],:]+$' ) then qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*:?' ) value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = value, inversed = isInversed } ) -- p123[p456!:q789] elseif mw.ustring.match( subRule, '^[Pp]%d+%s*!:%s*[^%[%],:]+$' ) then qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*!:?' ) value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = value, inversed = not isInversed } ) -- p123[q456] elseif mw.ustring.match( subRule, '^[Qq]%d+$' ) then value = mw.ustring.match( subRule, '^[Qq]%d+' ) table.insert( commands, { type = 'value', value = value, inversed = isInversed } ) else throwError( 'cant-parse-condition' ) end end if #commands then table.insert( rules, commands ) end rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos ) end return rules end --[[ Intercept statements with selector rules Input: statements table, selector rules Output: filtered statements table ]] function p.applyRules( claims, rules ) for i, subRules in ipairs( rules ) do local newClaims = {} for j, rule in ipairs( subRules ) do if rule['type'] == 'rank' then table.insert( newClaims, p.filterByRank( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'language' then table.insert( newClaims, p.filterByLanguage( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'unit' then table.insert( newClaims, p.filterByUnit( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'position' then table.insert( newClaims, p.filterByPosition( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'qualifier' then table.insert( newClaims, p.filterByQualifier( claims, rule['qualifier'], rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'qualifier_min' then table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], true ) ) elseif rule['type'] == 'qualifier_max' then table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], false ) ) elseif rule['type'] == 'value' then table.insert( newClaims, p.filterByValue( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'value_min' then table.insert( newClaims, p.filterUtter( claims, true ) ) elseif rule['type'] == 'value_max' then table.insert( newClaims, p.filterUtter( claims, false ) ) end end claims = {} --[[ Merge all claims TODO: It's not good ]] for j, newSubClaims in ipairs( newClaims ) do for k, newClaim in ipairs( newSubClaims ) do local isNew = true for l, oldClaim in ipairs( claims ) do if oldClaim['id'] == newClaim['id'] then isNew = false break end end if isNew then table.insert( claims, newClaim ) end end end end return claims end --[[ Filter statements by rank Input: claims table, rank value, inversion Output: filtered statements table ]] function p.filterByRank( claims, rank, inversed ) if not inversed then inversed = false end if not rank then rank = 'best' end -- Check if rank value is valid local isValidRank = false for i, validRank in ipairs( validRanks ) do if rank == validRank then isValidRank = true break end end if not isValidRank then throwError( 'rank-not-valid' ) end -- Find the best rank if rank == 'best' then rank = 'normal' -- default rank (don't use deprecated even if it's no more claims) -- If we have at least one preferred rank, mark it as best for i, statement in pairs( claims ) do if (statement.rank == 'preferred') then rank = 'preferred' break end end end local resultClaims = {}; for i, statement in pairs( claims ) do if ( statement.rank == rank ) ~= inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Filter statements by language of value Input: claims table, language, inversion Output: filtered statements table ]] function p.filterByLanguage( claims, language, inversed ) if not inversed then inversed = false end local resultClaims = {} local mulStatement = {} for i, statement in ipairs( claims ) do isMatchLanguage = false if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['value'] and statement['mainsnak']['datavalue']['value']['language'] then if statement['mainsnak']['datavalue']['value']['language'] == language then isMatchLanguage = true end if statement['mainsnak']['datavalue']['value']['language'] == 'mul' then mulStatement = statement end end if isMatchLanguage ~= inversed then table.insert( resultClaims, statement ) end end if next(resultClaims) == nil and next(mulStatement) ~= nil then -- if specific language is not found, but there is Q20923490 value table.insert( resultClaims, mulStatement ) end return resultClaims end --[[ Filter statements by unit of value Input: claims table, unit, inversion Output: filtered statements table ]] function p.filterByUnit( claims, unit, inversed ) if not inversed then inversed = false end unit = 'http://www.wikidata.org/entity/' .. string.upper( unit ) local resultClaims = {} for i, statement in ipairs( claims ) do isMatchUnit = false if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['value'] and statement['mainsnak']['datavalue']['value']['unit'] and statement['mainsnak']['datavalue']['value']['unit'] == unit then isMatchUnit = true end if isMatchUnit ~= inversed then table.insert( resultClaims, statement ) break end end return resultClaims end --[[ Filter statements by position Input: claims table, position, inversion Output: filtered statements table ]] function p.filterByPosition( claims, position, inversed ) if not inversed then inversed = false end local resultClaims = {}; for statementPosition, statement in ipairs( claims ) do if ( statementPosition == tonumber( position ) ) ~= inversed then table.insert( resultClaims, statement ) break end end return resultClaims end --[[ Filter statements by qualifier existance or it's value Input: claims table, ID of qualifier's property, qualifier's value, inversion Output: filtered statements table ]] function p.filterByQualifier( claims, qualifierId, value, inversed ) if not inversed then inversed = false end qualifierId = string.upper( qualifierId ) local resultClaims = {} for i, statement in ipairs( claims ) do if statement['qualifiers'] and statement['qualifiers'][qualifierId] then if value == nil then if ( #statement['qualifiers'][qualifierId] > 0 ) ~= inversed then table.insert( resultClaims, statement ) end else local isQualifierFound = false for j, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do if qualifier['datavalue'] then local qualifierValue = qualifier['datavalue']['value'] if qualifier['datavalue']['type'] == 'wikibase-entityid' then qualifierValue = qualifierValue.id value = string.upper( value ) end if qualifierValue == value then isQualifierFound = true break end end end if isQualifierFound ~= inversed then table.insert( resultClaims, statement ) end end elseif inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Filter statements by it's values Input: claims table, value, inversed Output: filtered statements table ]] function p.filterByValue( claims, value, inversed ) inversed = inversed or false local resultClaims = {} for i, statement in ipairs( claims ) do local statementValue if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['type'] then statementValue = statement['mainsnak']['datavalue']['value'] if statement['mainsnak']['datavalue']['type'] == 'quantity' then statementValue = statementValue.amount end if statement['mainsnak']['datavalue']['type'] == 'time' then statementValue = statementValue.time end if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then statementValue = statementValue.id value = string.upper( value ) end end if ( statementValue == value ) ~= inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Find a statement with minimum or maximum value Input: claims table, asc, inversed Output: filtered statements table ]] function p.filterUtter( claims, asc, inversed ) local resultValue = nil for i, statement in ipairs( claims ) do local statementValue if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['type'] then statementValue = statement['mainsnak']['datavalue']['value'] if statement['mainsnak']['datavalue']['type'] == 'quantity' then statementValue = statementValue.amount end if statement['mainsnak']['datavalue']['type'] == 'time' then statementValue = statementValue.time end if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then statementValue = statementValue.id end if not resultValue or ( statementValue < resultValue ) == asc then resultValue = statementValue end end end mw.logObject( resultValue, 'resultValue' ) return p.filterByValue( claims, resultValue, inversed ) end --[[ Find a statement with minimum or maximum qualifier value Input: claims table, qualifierId, asc Output: filtered statements table ]] function p.filterUtterByQualifier( claims, qualifierId, asc ) qualifierId = string.upper( qualifierId ) local resultValue = nil local resultStatement = nil for i, statement in ipairs( claims ) do if not statement['qualifiers'] and not statement['qualifiers'][qualifierId] then if resultStatement == nil then resultStatement = statement end else for _, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do if qualifier['datavalue'] then local qualifierValue = qualifier['datavalue']['value'] if qualifier['datavalue']['type'] == 'quantity' then qualifierValue = qualifierValue.amount end if qualifier['datavalue']['type'] == 'time' then qualifierValue = qualifierValue.time end if qualifier['datavalue']['type'] == 'wikibase-entityid' then qualifierValue = qualifierValue.id end if not resultValue or ( qualifierValue < resultValue ) == asc then resultStatement = statement resultValue = qualifierValue end end end end end return { resultStatement } end return p 0bdff3a63bf171160cdec5c966211fbbf3003880 Модуль:Calendar 828 17 44 2023-05-17T17:44:45Z wikipedia, ruwikipedia>Dima st bk 0 + короткие варианты для английского, см. [[Обсуждение шаблона:Cite web#Формат параметра %7Carchive-date=]] Scribunto text/plain local p = {} -- Необходимые модули и переменные local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local mwlang = mw.getContentLanguage() local err = "―" -- NthDay nil result local tCon = table.concat -- 00) Блок многократно используемых списков local bool_to_number={ [true]=1, [false]=0 } local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"} local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6, ["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""} local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local params = { {"г", "g"}, {"ю", "j"}} local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'} -- duplicates: -- AST, BST, CST, ECT, IST, MST, PST, SST, local known_tzs = { ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00', AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00', AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00', AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00', BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00', BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30', CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45', CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00', COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00', CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00', ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00', EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00', GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00', GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00', HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30', IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00', LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30', MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30', MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30', NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00', PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00', SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00', SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00', UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00', WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00', -- US Millitary (for RFC-822) Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00', } local category = { ["no_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->", ["incomplete_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->", ["without_verification"]= "<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->", ["erroneous_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->" } -- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением local e = { ["start"]="<span class=error>Ошибка: ", ["ending"]=".</span>", ["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами", ["no_valid_date"]="дата «%s» не является корректной", ["wrong_jd"]="юлианская дата %s вне диапазона", ["no_data"]="нет входящих данных", ["too_many_arguments"]="ожидается менее %i аргументов", ["too_little_arguments"]="ожидается более %i аргументов", ["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница", ["unknown_param"]="параметр %s неизвестен", ["unknown_error"]="неизвестная ошибка", ["tech_error"]="ошибка в функции %s", ["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД" -- [""]="", } local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST", "AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT", "BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST", "CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT", "CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT", "FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST", "HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST", "LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT", "NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT", "SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET", "VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"} local pattern = { -- для распознавания дат, переданных одним строчным параметром {"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd {"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy {"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy {"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm {"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y {"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y {"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y } local time_units = {"year","month","day"} --не используется --[[ local time_units = {"second", "minute", "hour", "day_of_month", "day_of_week", "day_of_year", "week", "month", "year", "year_of_century", "century"} ]]-- -- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"} local month_lang = { ["ru_G"] = {"января","февраля","марта","апреля","мая","июня", "июля","августа","сентября","октября","ноября","декабря"}, ["ru_N"] = {"январь","февраль","март","апрель","май","июнь", "июль","август","сентябрь","октябрь","ноябрь","декабрь"}, ["en"] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}, ["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}, ["de"] = {"januar", "februar", "märz", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "dezember"}, ["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"} } -- заполняется автоматически local reverse_month_lang = {} -- вспомогательная функция для обращения таблиц (смена ключей со значениями) local reverse_table = function (strait_table) local reversed_table = {} for k,v in pairs(strait_table) do reversed_table[v] = k end return reversed_table end -- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат local filling_months = function (mnlang, month_lang) for i=1, #mnlang do reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]]) end end -- 10) Блок общих функций local function trim(str) if not str then return nil else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)' end end local function purif(str) if str == "" or str == nil then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else return nil end -- need .5 -- ,5 number format converter? end local function is(str) if (not str) or (str == "") then return false else return yesno(str,false) end end local function init(num) local output = {} for i=1,num do table.insert(output, {["year"]="", ["month"]="", ["day"]=""}) end return unpack(output) end local function isyear(tbl) if type(tbl) ~= 'table' then return false elseif not tbl["year"] then return false elseif type(tbl["year"]) == 'number' then return true else return false end end local function inbord(val, down, up) return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up) end local function shallowcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[orig_key] = orig_value end else -- number, string, boolean, etc copy = orig end return copy end local inlist = function ( var, list ) local n = #list local inlist = false for i=1,n do if var == list[i] then inlist = true end end return inlist end -- 20) Блок общих проверочных функций, связанных с датами local function unwarp(tbl) if not tbl then return "" elseif type(tbl) ~= "table" then return tbl elseif (tbl.day or tbl.month or tbl.year) then return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?") else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?") end end local function leap_year(y,jul) if (not y) or (type(y) ~= "number") then return false elseif (y % 4) ~= 0 then return false elseif not jul and (y % 100 == 0 and y % 400 ~= 0) then return false else return true end end -- функция для вычисления последнего дня месяца для юлианского и григорианского календарей local function month_end_day (month,year,is_julian) local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil elseif month ~= 2 or not year then return month_end_day[month] elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29 elseif month == 2 then return 28 else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях end end local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year if not chain then return false elseif (not type(chain) == "table") or (not inbord(chain.year,-9999,9999)) or (not inbord(chain.month,1,12)) or (not inbord(chain.day,1,31)) or chain.day > monthd[chain.month] -- or chain.year == 0 then return false elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul) then return false else return true end -- check for other calendars needed? end local function ispartdate ( chain ) if not chain then return false elseif not (type(chain) == "table") then return false elseif (inbord(chain.year,-9999,9999) or inbord(chain.month,1,12) or inbord(chain.day,1,31)) then return true else return false end -- partial date -- more detailed check for 31.02.0000 needed -- check for other calendars needed end -- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed) local function partdist(date1,date2) local mont, dist = 0, 0 local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "") if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end -- нужна доп. проверка частичных дат на корректность if (inbord(d1m,1,12) or inbord(d2m,1,12)) and (d1m == "" or d2m == "") then mont = purif(date1["month"] or date2["month"]) d1m, d2m = mont, mont end -- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m ) if (inbord(d1m,1,12) and d1d <= monthd[d1m]) and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then if d2m == d1m then dist = d2d - d1d else dist = monthd[d1m] - d1d + d2d end return dist else return math.huge end end local function dmdist(d1,d2) local p1,p2 = math.huge,math.huge if not not partdist(d1,d2) then p1=partdist(d1,d2) end if not not partdist(d2,d1) then p1=partdist(d2,d1) end -- if (not p1) or (not p2) then -- return (p1 or "") .. (p2 or "") -- else -- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2)) return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge) -- end end -- 30) Блок функций для обработки ввода-вывода дат local function undate(tbl) if not tbl then return "" else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "") end end -- функция для нормализации значений дат и перевода месяцев в числа local function numerize(str) if type(str) == "number" then return math.floor(str) elseif str == "" or str == nil or type(str) ~= "string" then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else for i=1, #mnlang do if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)] end end end end -- функция распознавания даты, переданной одной строкой local function parse_date(date_string) if type(date_string) ~= "string" or date_string == "" then return nil end local out_date_str = {"","",""} local error_data = {} for i=1, #pattern do local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1]) if (result_1 or "") > "" then out_date_str[pattern[i].order[1]] = result_1 out_date_str[pattern[i].order[2]] = result_2 if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end -- mw.log("Паттерн " .. i .. ", строка: " .. date_string) break end end local date = { ["day"] =numerize(out_date_str[1]), ["month"]=numerize(out_date_str[2]), ["year"] =numerize(out_date_str[3])} return date --, error_data end ----[[ УСТАРЕЛО ]]---- local numstr2date = function(numstr) local format = "Y-m-d" local iso_date = mwlang:formatDate(format,numstr) local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)") local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)} return dateout end --local numstr2date = function(numstr) -- local nums = {} -- local dateout = {} -- for num in string.gmatch(numstr,"(%d+)") do -- table.insert(nums,purif(num)) -- end -- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums) -- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден") -- elseif not inbord(nums[3],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- elseif not inbord(nums[1],1,31) then -- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]} -- elseif inbord(nums[1],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- else -- local mwlang = mw.getContentLanguage() -- implement mwlang:formatDate(format,datein,true) here -- return error("Не распознано " .. numstr .. " как дата") -- end -- return dateout --end local function year2lang(numyear,yearmark,wiki) if not numyear then return "" end if not yearmark then yearmark = "" end local output = "" local bcmark = " до н. э." if numyear > 0 then bcmark = "" else numyear = 1 - numyear end if wiki then -- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark}) output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'}) else output = tCon({numyear, " ", yearmark, bcmark}) end return trim(output) end local function day2lang(datein,wikidate,wiki,inner_brt) -- if not isdate(wikidate) then wiki = false end if not ispartdate(datein) then return "" end local dm_separ, output = "", nil if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end if (not datein.month) then datein.month = "" end if (not datein.day) then datein.day = "" end local monlan = monthlang[datein.month] or "" if wiki and not inner_brt then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan, "]]"}) elseif wiki then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan}) else output = tCon({datein.day, dm_separ, monlan}) end return trim(output) end local function triple_txt2date(d,m,y) -- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи -- mw.ustring.match((m or ""),"(%a+)") local msg = "" local year = purif((y or "-"):match("(%d+)")) local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))]) local day = purif((d or "-"):match("(%d+)")) if not month then msg = category.incomplete_parameters month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")]) end if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then msg = category.incomplete_parameters day = purif(m:match("(%d+)") or "") end if not year then msg = category.incomplete_parameters year = purif(string.match(m or "","(%d+)") or "") end local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg} return dateout end local function glue(d1,m1,y1,d2,m2,y2) if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then return category.incomplete_parameters end local gd,gm,gy,jd,jm,jy = (d1 or ""), (m1 or ""), (y1 or ""), (d2 or ""), (m2 or ""), (y2 or "") --mw.log(tCon({gd,gm,gy,jd,jm,jy})) local gm_sep = {" [["," год|","]]"} if (not gy) or (gy == "") then gm_sep = {"","",""} end return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ), comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""), gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters}) end -- добавить отображение без года local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) local msg = "" msg = (jdate.msg or "") .. (gdate.msg or "") local cd = {} local jd = shallowcopy(jdate) local gd = shallowcopy(gdate) local left = "(" local right = ")" if sq_brts then left = "&#091;" right = "&#093;" end if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата") elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end if jd.year == gd.year then cd.year = gd.year gd.year, jd.year = nil, nil end if jd.month == gd.month then cd.month = gd.month gd.month, jd.month = nil, nil end if (not not cd.month) and wm then return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end -- 40) Блок функций для перевода дат с использованием [[Юлианская дата]] local function gri2jd( datein ) if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1931076.5, 5373557.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2jul( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local c = jd + 32082 local d = math.floor((4*c + 3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e + 2)/153) local year_out = d - 4800 + math.floor(m/10) local month_out = m + 3 - 12*math.floor(m/10) local day_out = e - math.floor((153*m + 2)/5) + 1 -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function jul2jd( datein ) if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - 32083 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1930999.5, 5373484.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2gri( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local a = jd + 32044 local b = math.floor((4*a + 3) / 146097) local c = a - math.floor(146097*b/4) local d = math.floor((4*c+3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e+2)/153) local day_out = e - math.floor((153*m+2)/5)+1 local month_out = m + 3 - 12*math.floor(m/10) local year_out = 100*b + d - 4800 + math.floor(m/10) -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function astroyear(num, bc) if not num then return error() elseif type(num) ~= "number" then return error() end if num < 1 then return num end if not bc then return num else return 1 - num end end local function recalc(datein,calend) if inlist(calend,params[1]) then return jd2jul(gri2jd(datein)), datein elseif inlist(calend,params[2]) then return datein, jd2gri(jul2jd(datein)) else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," ")) end end -- 50) Функции для обработки UTC local function utc(str,margin) local d = 1 local dchar = "+" local beginning = "[[UTC" local ending = "]]" local cat = "" local nums = {} local hmarg, timedec = 0, 0 local mmarg = "00" local output = "" -- checking type of input if not margin then margin = 0 elseif type(tonumber(margin)) ~= 'number' then output = "Can't shift by " .. margin error(output) end if type(str) ~= 'string' then error("Нет входящей строки") elseif str:byte(1) == 43 then elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]" elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1 else error(string.char(str:byte(1)) .. " недопустимый первый символ") end -- parsing input for num in string.gmatch(str,"(%d+)") do table.insert(nums,purif(num)) end if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums) elseif #nums == 0 then error("Необходимо что-то ввести") elseif #nums == 1 then if inbord(nums[1],0,14) then timedec = d*nums[1] + margin else error("Только часы от -14 до 14") end elseif #nums == 2 then if not inbord(nums[1],0,14) then error("Только часы от -14 до 14") elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59") else timedec = d*(nums[1] + nums[2]/60) + margin end end if tonumber(timedec) == purif(timedec) then hmarg = timedec else local h, m = math.modf(math.abs(timedec)) hmarg = h mmarg = math.floor(m*60) end if timedec == 0 then dchar = "±" elseif timedec > 0 then elseif timedec < 0 then dchar = "&minus;" end -- output output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat return output end -- 60) Блок функций ввода-вывода function p.NthDay( frame ) local args = getArgs(frame, { frameOnly = true }) local num, wday, mont, yea, format = purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5] if not format then format = "%d.%m.%y" end if not inbord(num,-5,5) then return error("The number must be between -5 and 5") elseif num == 0 then return error("The number must not be zero") end if not inbord(wday,0,6) then return error("The day of the week must be between 0 and 6") end if not inbord(mont,1,12) then return error("The month must be between 1 and 12") end if not inbord(yea,0,9999) then return error("Wrong year number") end if inbord(num,1,5) then local m_start = os.time{year=yea, month=mont, day=1, hour=0} local m_wds = tonumber(os.date("%w", m_start)) local start_shift = ( (num - bool_to_number[wday >= m_wds]) * 7 - (m_wds - wday) ) * 24 * 60 * 60 local tim = m_start + start_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end elseif inbord(num,-5,-1) then local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60 local m_wde = tonumber(os.date("%w", m_end)) local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7 + (m_wde - wday)) * 24 * 60 * 60 local tim = m_end - end_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end end end -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) function p.ToIso( frame ) local args = getArgs(frame, { frameOnly = true }) local datein = args[1] -- инициализация, заполнение обратных таблиц, копирование параметров filling_months(mnlang, month_lang) -- парсинг входящей даты по шаблону local date = parse_date(datein) if not (type(date.year) == 'number') then return ("Wrong year: " .. unwarp(date)) end if not (1 <= date.month and date.month <= 12) then return ("Wrong month: " .. unwarp(date)) end if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then return ("Wrong day: " .. unwarp(date)) end local timedate = os.time{year=date.year, month=date.month, day=date.day} local date = os.date("%Y-%m-%d", timedate) return date end -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}}) function p.BoxDate( frame ) local args = getArgs(frame, { frameOnly = true }) local txtDateIn, strFormat = args[1], args[2] local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end function p.bxDate( txtDateIn , strFormat, params ) -- к отладке local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""} strFormat = strFormat or "j xg Y" -- заглушка - таблица параметров на будущее params = params or {} if not txtDateIn then status.errorText = e.no_data status.errorCat = category.no_parameters status.brk = true else -- заполнение служебных таблиц filling_months(mnlang, month_lang) end if not status.brk then -- парсинг входящей даты по шаблону date = parse_date(txtDateIn) -- заменить сообщения об ошибках на списочные if not (date.year and type(date.year) == 'number') then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not inbord(date.month,1,12) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not date.day and string.find(strFormat,"[dDjlNwzW]") then strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]","")) elseif not date.day then elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end end if not status.brk then txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true) end return txtDateOut, date, status end function p.ToDate( frame ) -- возможно неиспользуемая local args = getArgs(frame, { frameOnly = true }) local mwlang = mw.getContentLanguage() local datein = args[1] local format = "j xg Y" if not string.match(datein, "%p") then return datein elseif not args[2] then else format = args[2] end return mwlang:formatDate(format,datein,true) end -- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}}) function p.unitime( frame ) local args = getArgs(frame, { frameOnly = true }) local DST = 0 if not args[2] then else DST = 1 end local utcin = "" local input = args[1] if not input then return "" end if inlist(input:upper(),tzs_names) then utcin = known_tzs[input:upper()] elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then utcin = string.sub(input,4) else if string.sub(input,1,1) == '[' or string.sub(input,1,1) == '{' or string.sub(input,1,1):upper() == 'U' or string.sub(input,1,1):upper() == 'M' then return input -- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or -- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then -- return input else utcin = input end end -- elseif string.sub(input,1,3) ~= "−" then utcin = input -- or not (not input:find("[А-я]")) при наличии в строке юникода не работает local output = "" if DST == 0 then output = utc(utcin) else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST) end return output end -- УСТАРЕЛО -- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) function p.OldDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local gdate, jdate = {}, {} local strin = args[1] local cal = args[2]:lower() or "г" local bc = is(args["bc"]) local wd = is(args["wd"]) local wm = is(args["wm"]) local wy = is(args["wy"]) if not wd then wm = false end local sq_brts = is(args["sq_brts"]) local yearmark = "года" if yesno(args["yearmark"]) then elseif yesno(args["yearmark"]) == false then yearmark = "" else yearmark = trim(args["yearmark"]) or "года" end -- local infocard = is(args["infocard"]) -- local catName = args["catName"] or false local datein = numstr2date(strin) datein.year = astroyear(datein.year, bc) jdate, gdate = recalc(datein,cal) return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}}) function p.NewDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local strin = args[1] local year, month, day if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" ) elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) end if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy") end local cal = "г" if (not args[2]) or (args[2] == "") then cal = "г" else cal = args[2]:lower() end local bc,wd,wm,wy,sq_brts = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]) year = astroyear(purif(year),bc) local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)} local jdate, gdate = recalc(datein,cal) local yearmark = "года" local ym = args["yearmark"] or "" if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}}) -- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}} function p.Test( frame ) local args = getArgs(frame, { frameOnly = true }) -- необходима проверка и замена nil на " " --[[mw.log((args[1] or "") .. " " .. (args[2] or "") .. " " .. (args[3] or "") .. " " .. (args[4] or "") .. " " .. (args[5] or "") .. " " .. (args[6] or "")) ]]-- local ingdate = triple_txt2date(args[1],args[2],args[3]) local injdate = triple_txt2date(args[4],args[5],args[6]) local j1date, g1date, j2date, g2date = init(4) mw.log("ingdate-".. (undate(ingdate) or "")) mw.log("injdate-".. (undate(injdate) or "")) local bc,wd,wm,wy,sq_brts,ny = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]), is(args["ny"]) -- подавление формата для локальных тестов local wd, wm, wy = true, true, true local yearmark = "года" local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "") -- mw.log("ym " .. ym) if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end if isdate(ingdate) or isdate(injdate) then if isdate(ingdate) then j1date, g1date = recalc(ingdate,"g") ingdate["full"] = true end if isdate(injdate) then j2date, g2date = recalc(injdate,"j") injdate["full"] = true end if ispartdate(ingdate) and ispartdate(injdate) then mw.log("📏 " .. dmdist(ingdate,injdate)) mw.log("📏 " .. dmdist(j1date,g1date)) mw.log("📏 " .. dmdist(j2date,g2date)) mw.log("📏 " .. dmdist(ingdate,g1date)) mw.log("📏 " .. dmdist(injdate,j2date)) end end if ny then if isyear(j1date) then else j1date["year"] = "" end if isyear(j2date) == nil then else j2date["year"] = "" end if isyear(g1date) == nil then else g1date["year"] = "" end if isyear(g2date) == nil then else g2date["year"] = "" end end if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then if ((j1date.year == j2date.year) and (j1date.month == j2date.month) and (j1date.day == j2date.day)) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) else mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- категория (предположительная разница в днях) и частичный вывод end elseif isdate(j1date) and isdate(g1date) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif isdate(j2date) and isdate(g2date) then return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif (ispartdate(ingdate) and ispartdate(injdate)) then mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- частичный или полный вывод, категория else mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) return err .. category.incomplete_parameters end end return p a4a91f134ad3e3b246b3a6681a4ae438da766df4 Шаблон:Число 10 94 198 2023-06-20T10:24:09Z wikipedia, ruwikipedia>Stjn 0 лучше так тогда для лимитов wikitext text/x-wiki {{formatnum: {{replace|{{{1}}}|,|.}} }}{{#if: {{{1|}}} | {{#if: {{{2|}}} | {{nobr|1=&nbsp;{{{2|}}}}} }} }}<noinclude> {{doc}} </noinclude> acfc1e9cec817e6742b18106f020ac388ececc7e Шаблон:Карточка/оригинал названия 10 89 188 2023-07-04T10:53:52Z wikipedia, ruwikipedia>Wikisaurus 0 wikitext text/x-wiki {{wikidata|p1705[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<!-- -->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом названия без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude> 4eccda042428e1113ff320ff5d6b760a7f52b088 Шаблон:Государство 10 106 222 2023-07-18T14:45:13Z ruwikipedia>Krestenti 0 wikitext text/x-wiki {{Карточка |имя = Государство |автозаголовки = да |from = {{{from|}}} |вверху0 = {{#switch: {{{Статус|}}} | виртуальное = [[Виртуальное государство]] | особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }} | Непризнанное | непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }} | Частично признанное | частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }} }} |вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}} |вверху2 = {{карточка/оригинал названия|{{карточка/официальное название|{{{Оригинальное название|}}}|from={{{from|}}}}}|from={{{from|}}}}} |изображение = {{Карточка/флаг и герб | флаг = {{{Флаг|}}} | флаг ширина = {{{Размер флага|}}}{{{размер флага|}}} | флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]] | герб = {{{Герб|}}} | герб ширина = {{{Размер герба|}}}{{{размер герба|}}} | герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }} |from={{{from|}}}}} |текст1 = {{br separated entries | {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }} | {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }} }} |текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | {{br separated entries | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | {{#if: {{{Перевод названия гимна|}}} | ''«{{{Перевод названия гимна}}}»'' }} }} | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|center]] }} }} }} |текст3 = {{#if: {{wikidata|p242|{{{На карте|}}}|plain=true|from={{{from|}}}}} | {{wikidata|p242|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}|from={{{from|}}}}}<!-- -->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }} |заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }} |стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left; |блок5 = {{Карточка/блок с маркерами |метка1 = {{nobr|{{{Дата1}}}}} |текст1 = {{{Этап1|}}} |метка2 = {{nobr|{{{Дата2}}}}} |текст2 = {{{Этап2|}}} |метка3 = {{nobr|{{{Дата3}}}}} |текст3 = {{{Этап3|}}} |метка4 = {{nobr|{{{Дата4}}}}} |текст4 = {{{Этап4|}}} |метка5 = {{nobr|{{{Дата5}}}}} |текст5 = {{{Этап5|}}} |метка6 = {{nobr|{{{Дата6}}}}} |текст6 = {{{Этап6|}}} |метка7 = {{nobr|{{{Дата7}}}}} |текст7 = {{{Этап7|}}} |метка8 = {{nobr|{{{Дата8}}}}} |текст8 = {{{Этап8|}}} |метка9 = {{nobr|{{{Дата9}}}}} |текст9 = {{{Этап9|}}} |метка10 = {{nobr|{{{Дата10}}}}} |текст10 = {{{Этап10|}}} |метка11 = {{nobr|{{{Дата11}}}}} |текст11 = {{{Этап11|}}} |метка12 = {{nobr|{{{Дата12}}}}} |текст12 = {{{Этап12|}}} |from={{{from|}}}}} |заголовок6 = - |метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]] |текст7 = {{{Основана|}}}{{{Основано|}}} |викиданные7 = <!-- СПОРНЫЙ СТАТУС --> <!-- Спорный статус заполнен --> |метка8 = [[Основание государства|Дата образования]] |текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }} |викиданные8 = |метка9 = Провозглашение независимости |текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |викиданные9 = |метка10 = [[Международно-правовое признание|Дипломатическое признание]] |текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }} |викиданные10 = <!-- Спорный статус не заполнен --> |метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }} |текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |викиданные11 = <!-- / СПОРНЫЙ СТАТУС --> |метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]] |текст12 = {{{Язык|{{{Языки|}}}}}} |викиданные12 = p37 |метка13 = [[Столица]] |текст13 = {{{Столица|}}} |викиданные13 = p36 |метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }} |текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}} |викиданные14 = |метка15 = [[Форма государственного правления|Форма правления]] |текст15 = {{{Форма правления|}}} |викиданные15 = |метка16 = [[Форма государственного устройства|Государственный строй]] |текст16 = {{{Государственный строй|}}} |метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}} |текст17 = {{{Руководитель 1|{{{Руководители|}}}}}} |метка18 = {{{Должность руководителя 2}}} |текст18 = {{{Руководитель 2|}}} |метка19 = {{{Должность руководителя 3}}} |текст19 = {{{Руководитель 3|}}} |метка20 = {{{Должность руководителя 4}}} |текст20 = {{{Руководитель 4|}}} |метка21 = {{{Должность руководителя 5}}} |текст21 = {{{Руководитель 5|}}} |метка22 = {{{Должность руководителя 6}}} |текст22 = {{{Руководитель 6|}}} |метка23 = [[Государственная религия|Гос. религия]] |текст23 = {{{Государственная религия|}}} |викиданные23 = |блок24 = {{Карточка/блок с маркерами |подзаголовок = [[Территория государства|Территория]] |метка1 = Всего |текст1 = {{br separated entries | {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | &nbsp;{{nobr|([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]])}} }} | {{число|{{{Территория2|}}}|км²}} }} |метка2 = % водной поверхности |текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }} |from={{{from|}}}}} |блок25 = {{Карточка/блок с маркерами |подзаголовок = [[{{Население государства|{{PAGENAME}}}}]] |метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }} |текст1 = {{br separated entries | {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | &nbsp;([[Список стран по населению|{{{Место по населению}}}-е]]) }} | {{число|{{{Население2|}}}|чел.}} }} |метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }} |текст2 = {{число|{{{Население по переписи|}}}|чел.}} |метка3 = [[Плотность населения|Плотность]] |текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | &nbsp;([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }} |from={{{from|}}}}} |блок26 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] |метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }} |текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок27 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }} |текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок28 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }} |текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | &nbsp;([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | &nbsp;([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }} |from={{{from|}}}}} |метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }} |текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | &nbsp;({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | &#059; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е&nbsp;место]] }}) }} |викиданные29 = |метка30 = [[Названия жителей]] |текст30 = {{{Этнохороним|}}} |викиданные30 = |метка31 = [[Валюта]] |текст31 = {{{Валюта|}}} |викиданные31 = P38 |метка32 = [[Домен верхнего уровня|{{wikidata number switch|P78|{{{Домен|}}}|{{{Домены|}}}|Интернет-домен|Интернет-домены}}]] |текст32 = {{{Домен|}}}{{{Домены|}}} |викиданные32 = P78 |метка33 = [[ISO 3166-1|Код ISO]] |текст33 = |викиданные33 = P297 |метка34 = [[Список кодов МОК|Код МОК]] |текст34 = |викиданные34 = P984 |метка35 = [[Список телефонных кодов стран|Телефонный код]] |текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }} |викиданные35 = P474 |метка36 = [[Часовой пояс|{{wikidata number switch|P421|{{{Часовой пояс|}}}|{{{Часовые пояса|}}}|Часовой пояс|Часовые пояса}}]] |текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}} |викиданные36 = P421 |метка37 = Автомобильное движение |текст37 = {{{Автомобильное движение|}}} |викиданные37 = P1622 |текст38 = {{{Примечания|}}} |стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left; |внизу = {{карточка/Викисклад|from={{{from|}}}}} }}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#if: {{{lat_deg|}}} | {{coord|1={{{lat_deg|}}}|2={{{lat_min|0}}}|3={{{lat_sec|0}}}|4={{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }}|5={{{lon_deg|}}}|6={{{lon_min|0}}}|7={{{lon_sec|0}}}|8={{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }}|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|format=dms|display=title}} | {{#if: {{#property: p625}} | {{wikidata|p625|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|from={{{from|}}}}} | [[Категория:Государства без указанных географических координат]] }} }}<!-- -->{{#switch: {{{Статус|}}} | Виртуальное | виртуальное = [[Категория:Виртуальные государства]] | Непризнанное | непризнанное = [[Категория:Непризнанные государства]] | Частично признанное | частично признанное = [[Категория:Частично признанные государства]] | особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }} | [[Категория:Государства по алфавиту]] }}<!-- -->{{Государство/Викиданные}} }}<noinclude>{{doc}}</noinclude> d5532838af5967020fc4f653452458ba05aea4cf Шаблон:Скрытый блок 10 51 112 2023-12-21T00:36:59Z wikipedia, ruwikipedia>Stjn 0 неактуальный параметр wikitext text/x-wiki {{Начало скрытого блока |id = {{{id|}}} |тип = {{{тип|{{{type|}}}}}} |состояние = {{{state|{{{состояние|collapsed}}}}}} |класс_тела = {{{класс_тела|{{{класс тела|}}}}}} |стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}} |рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}} |ссылка = {{{Ссылка|{{{ссылка|}}}}}} |класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}} |шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}} |класс_текста = {{{класс_текста|{{{класс текста|}}}}}} |шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}} {{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}} {{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }} {{Конец скрытого блока}}<noinclude> {{doc}} </noinclude> 792dc9fb2eb659877e2e758f4ce405e1d3f8352b Модуль:Navbox 828 33 76 2024-02-23T14:27:31Z wikipedia, ruwikipedia>Stjn 0 переход на [[модуль:Navbar]] Scribunto text/plain -- -- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}. -- Основной объём кода заимствован из английского Module:Navbox. -- local p = {} local navbar = require('Module:Navbar')._ruwikiNavbar local getArgs -- lazily initialized local yesno -- lazily initialized local styleratio local ODD_EVEN_MARKER = '\127_ODDEVEN_\127' local RESTART_MARKER = '\127_ODDEVEN0_\127' local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127' -- общие параметры для всех шаблонов local commonAliases = { name = {'name', 'имя'}, navigation = {'navigation', 'навигация'}, navbar = {'navbar', 'ссылка_на_просмотр'}, state = {'state'}, orphan = {'orphan'}, tracking = {'tracking'}, border = {'border', 1}, title = {'title', 'заголовок'}, titlegroup = {'titlegroup'}, above = {'above', 'вверху'}, image = {'image', 'изображение'}, imageleft = {'imageleft', 'изображение2', 'изображение_слева'}, below = {'below', 'внизу'}, bodyclass = {'bodyclass', 'класс_тела'}, titleclass = {'titleclass', 'класс_заголовка'}, titlegroupclass = {'titlegroupclass'}, aboveclass = {'aboveclass', 'класс_вверху'}, belowclass = {'belowclass', 'класс_внизу'}, groupclass = {'groupclass', 'класс_групп'}, listclass = {'listclass', 'класс_списков'}, imageclass = {'imageclass', 'класс_изображения'}, basestyle = {'basestyle', 'стиль', 'стиль_базовый'}, bodystyle = {'style', 'bodystyle', 'стиль_тела'}, titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'}, titlegroupstyle = {'titlegroupstyle'}, innerstyle = {'innerstyle'}, abovestyle = {'abovestyle', 'стиль_вверху'}, belowstyle = {'belowstyle', 'стиль_внизу'}, imagestyle = {'imagestyle', 'стиль_изображения'}, imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} local standardAliases = { groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'}, liststyle = {'liststyle', 'стиль_списков'}, evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'}, groupwidth = {'groupwidth', 'ширина_групп'}, listpadding = {'listpadding', 'отступ_списков'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией local standardElementAliases = { group = {'group%s', 'заголовок%s', 'группа%s'}, list = {'list%s', 'список%s'}, groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'}, listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'}, liststyle = {'list%sstyle', 'стиль_списка%s'}, listpadding = {'list%spadding'} } -- параметры {{навигационная таблица с блоками}} -- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases local groupsParentAliases = { selected = {'selected', 'открытый_блок', 'развернуть'}, secttitlestyle = {'secttitlestyle', 'стиль_заголовков'}, _groupstyle = {'groupstyle', 'стиль_блоков'}, _liststyle = {'liststyle', 'стиль_списков', 'contentstyle'}, _listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'} } -- параметры {{навигационная таблица с блоками}} с нумерацией local groupsChildAliases = { groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'}, state = {'state%s'}, title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'}, list1 = {'list%s', 'список%s', 'content%s'}, image = {'image%s', 'изображение%s'}, imageleft = {'imageleft%s', 'изображение_слева%s'}, secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'}, groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'}, listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'}, liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'}, color = {'цвет%s'} } local function checkAliases(args, aliases, index) for _, alias in ipairs(aliases) do local arg if index then arg = args[string.format(alias, index)] else arg = args[alias] end if arg then return arg end end return nil end local function checkElAliases(args, name, index) return checkAliases(args, standardElementAliases[name], index) end local function concatStyles(t) local res for k, v in pairs(t) do if v then res = res and res .. ';' .. v or v end end return res end local function striped(wikitext, args) -- Return wikitext with markers replaced for odd/even striping. -- Child (subgroup) navboxes are flagged with a category that is removed -- by parent navboxes. The result is that the category shows all pages -- where a child navbox is not contained in a parent navbox. local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]' if args.border == 'subgroup' and args.orphan ~= 'yes' then -- No change; striping occurs in outermost navbox. return wikitext .. orphanCat end local first, second = 'odd', 'even' if args.evenodd then if args.evenodd == 'swap' then first, second = second, first else first = args.evenodd second = first end end local changer if first == second then changer = first else local index = 0 changer = function (code) if code == '0' then -- Current occurrence is for a group before a nested table. -- Set it to first as a valid although pointless class. -- The next occurrence will be the first row after a title -- in a subgroup and will also be first. index = 0 return first end index = index + 1 return index % 2 == 1 and first or second end end local regex = orphanCat:gsub('([%[%]])', '%%%1') return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count end local function addNewline(s) if s:match('^[*:;#]') or s:match('^{|') then return '\n' .. s ..'\n' else return s end end local function renderNavBar(titleCell, args) local currentFrame = mw.getCurrentFrame() if args.navbar ~= 'off' and args.navbar ~= 'plain' and (args.name or not currentFrame:getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then --- Gear creation titleCell :tag('span') :addClass('navbox-gear') :css('float', 'left') :css('text-align', 'left') :css('width', '5em') :css('margin-right', '0.5em') :wikitext(navbar{ args.name, ['fontstyle'] = args.titlestyle or args.basestyle }) end end -- -- Title row -- local function renderTitleRow(tbl, args) if not args.title then return end local titleRow = tbl:tag('tr') if args.titlegroup then titleRow :tag('th') :attr('scope', 'row') :addClass('navbox-group') :addClass(args.titlegroupclass) :cssText(args.basestyle) :cssText(args.groupstyle) :cssText(args.titlegroupstyle) :wikitext(args.titlegroup) end local titleCell = titleRow:tag('th'):attr('scope', 'colgroup') if args.titlegroup then titleCell :css('border-left', '2px solid #fdfdfd') :css('width', '100%') end local titleColspan = 2 if args.imageleft then titleColspan = titleColspan + 1 end if args.image then titleColspan = titleColspan + 1 end if args.titlegroup then titleColspan = titleColspan - 1 end titleCell :cssText(args.basestyle) :cssText(args.titlestyle) :addClass('navbox-title') :attr('colspan', titleColspan) renderNavBar(titleCell, args) titleCell :tag('div') :attr('id', mw.uri.anchorEncode(args.title)) :addClass(args.titleclass) :css('font-size', '114%') :css('margin', '0 5em') :wikitext(addNewline(args.title)) end -- -- Above/Below rows -- local function getAboveBelowColspan(args) local ret = 2 if args.imageleft then ret = ret + 1 end if args.image then ret = ret + 1 end return ret end local function renderAboveRow(tbl, args) if not args.above then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.aboveclass) :cssText(args.basestyle) :cssText(args.abovestyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.above)) end local function renderBelowRow(tbl, args) if not args.below then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.belowclass) :cssText(args.basestyle) :cssText(args.belowstyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.below)) end -- -- List rows -- local function haveSubgroups(args) for i = 1, 23 do if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then return true end end return false end local function renderListRow(tbl, args, index, rowspan, rowArgs) local row = tbl:tag('tr') if index == 1 and args.imageleft then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 7px 0px 0px') :cssText(args.imageleftstyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.imageleft)) end if rowArgs.group then local groupCell = row:tag('th') groupCell :attr('scope', 'row') :addClass('navbox-group') :addClass(args.groupclass) :cssText(args.basestyle) :css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width groupCell :cssText(args.groupstyle) :cssText(rowArgs.groupstyle) :wikitext(rowArgs.group) end local listCell = row:tag('td') if rowArgs.group then listCell :css('text-align', 'left') :css('border-left-width', '2px') :css('border-left-style', 'solid') else if haveSubgroups(args) then listCell :attr('colspan', 2) end end if not args.groupwidth then listCell:css('width', '100%') end local listText = rowArgs.list local oddEven = ODD_EVEN_MARKER if listText:sub(1, 12) == '</div><table' then -- Assume list text is for a subgroup navbox so no automatic striping for this row. oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd' end listCell :css('padding', '0px') :cssText(args.liststyle) :cssText(rowArgs.liststyle) :addClass('navbox-list') :addClass('navbox-' .. oddEven) :addClass(args.listclass) :addClass(rowArgs.listclass) :tag('div') :css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em') :wikitext(addNewline(listText)) if index == 1 and args.image then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 0px 0px 7px') :cssText(args.imagestyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.image)) end end -- -- Tracking categories -- local function needsChangetoSubgroups(args) for i = 1, 23 do if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then return true end end return false end local function needsHorizontalLists(args) if args.border == 'subgroup' or args.tracking == 'no' then return false end local listClasses = { ['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true, ['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true, ['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true, } return not (listClasses[args.listclass] or listClasses[args.bodyclass]) end -- local function hasBackgroundColors() -- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background') -- end local function isIllegible(args) if not styleratio then styleratio = require('Module:Color contrast')._styleratio end for key, style in pairs(args) do if tostring(key):match("style$") or tostring(key):match("^стиль") then if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then return true end end end return false end local function getTrackingCategories(args) local cats = {} if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end return cats end local function renderTrackingCategories(builder, args) local title = mw.title.getCurrentTitle() if title.namespace ~= 10 then return end -- not in template space local subpage = title.subpageText if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end for i, cat in ipairs(getTrackingCategories(args)) do builder:wikitext('[[Категория:' .. cat .. ']]') end end -- -- Main navbox tables -- local function renderMainTable(args, listnums) local tbl = mw.html.create('table') :addClass('nowraplinks') :addClass(args.bodyclass) if args.title and (args.state ~= 'plain' and args.state ~= 'off') then tbl :addClass('collapsible') :addClass(args.state or 'autocollapse') end tbl:css('border-spacing', 0) if args.border == 'subgroup' or args.border == 'none' then tbl :addClass('navbox-subgroup') :cssText(args.bodystyle) else -- regular navbox - bodystyle and style will be applied to the wrapper table tbl :addClass('navbox-inner') :css('background', 'transparent') :css('color', 'inherit') end tbl:cssText(args.innerstyle) renderTitleRow(tbl, args) renderAboveRow(tbl, args) for i, listnum in ipairs(listnums) do local rowArgs = { group = checkElAliases(args, 'group', listnum), list = checkElAliases(args, 'list', listnum), groupstyle = checkElAliases(args, 'groupstyle', listnum), listclass = checkElAliases(args, 'listclass', listnum), liststyle = checkElAliases(args, 'liststyle', listnum), listpadding = checkElAliases(args, 'listpadding', listnum) } renderListRow(tbl, args, i, #listnums, rowArgs) end renderBelowRow(tbl, args) return tbl end -- Read the arguments in the order they'll be output in, to make references number in the right order. local function readInTheRightOrder(args, groupAliases, listAliases) local _ _ = checkAliases(args, commonAliases.title) _ = checkAliases(args, commonAliases.above) for i = 1, 23 do _ = checkAliases(args, groupAliases, i) _ = checkAliases(args, listAliases, i) end _ = checkAliases(args, commonAliases.below) end function p._navbox(args) if not yesno then yesno = require('Module:Yesno') end local listnums = {} for k, v in pairs(args) do local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$') if listnum then table.insert(listnums, tonumber(listnum)) end end table.sort(listnums) args.border = mw.text.trim(args.border or args[1] or '') if args.border == 'child' then args.border = 'subgroup' end for argname, aliasesList in pairs(commonAliases) do args[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(standardAliases) do args[argname] = checkAliases(args, aliasesList) end args.navigation = yesno(args.navigation, '') -- render the main body of the navbox local tbl = renderMainTable(args, listnums) -- render the appropriate wrapper around the navbox, depending on the border param local res = mw.html.create() if args.border == 'none' then local nav = res:tag('div') :attr('role', 'navigation') :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end elseif args.border == 'subgroup' then -- We assume that this navbox is being rendered in a list cell of a parent navbox, and is -- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the -- padding being applied, and at the end add a <div> to balance out the parent's </div> res :wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html. :node(tbl) :wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html. else local nav = res:tag('div') :attr('role', 'navigation') :addClass('navbox') :cssText(args.bodystyle) :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end end renderTrackingCategories(res, args) return striped(tostring(res), args) end function p.navbox(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end if not yesno then yesno = require('Module:Yesno') end args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}}) if frame.args.border then -- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}. args.border = frame.args.border end readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list) return p._navbox(args) end function p.navboxWithCollapsibleGroups(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}}) readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1) local parent = {} for argname, aliasesList in pairs(commonAliases) do parent[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(groupsParentAliases) do parent[argname] = checkAliases(args, aliasesList) end for i = 1, 20 do local child = {} for argname, aliasesList in pairs(groupsChildAliases) do child[argname] = checkAliases(args, aliasesList, i) end child.color = child.color and string.format('background:%s;', child.color) or '' child.border = 'child' child.navbar = 'plain' if parent.selected and parent.selected == child.groupname then child.state = 'uncollapsed' end child.state = child.state or 'collapsed' child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle} child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color} child.liststyle = concatStyles{parent._liststyle, child.liststyle} child.lispadding = parent._listpadding if child.title then parent['list' .. i] = p._navbox(child) else parent['list' .. i] = child.list1 end end return p._navbox(parent) end return p cf72974326d19e1d4d58d2d00766b944b3ca0944 Шаблон:Навигационная таблица 10 37 84 2024-02-26T11:53:15Z wikipedia, ruwikipedia>Stjn 0 тоже может иметь эти значения wikitext text/x-wiki <includeonly>{{#invoke:Navbox|navbox}}</includeonly>{{#ifeq: {{NAMESPACE}} | Шаблон | {{#switch: {{{1|{{{border|}}}}}} | child | subgroup | none = | {{#ifeq: {{{имя|{{{name|}}}}}} | {{PAGENAME}} | | {{#if:{{yesno|{{{tracking|}}}|no=1|yes=|blank=}} | | {{#if: {{{имя|{{{name|}}}}}} | {{#ifeq:{{ROOTPAGENAME}}|Работа недели||{{no-doc|[[Категория:Навигационные шаблоны, у которых нужно проверить параметр Имя]]}}}} | [[Категория:Навигационные шаблоны, у которых предположительно недостаёт параметра Имя]] }} }} }} }} }}<noinclude> {{doc}} </noinclude> b1c7f6e61d3b9cdd1daaf4d95e30e299a1d9eb5c Модуль:Message box 828 15 40 2024-03-25T18:05:03Z wikipedia, ruwikipedia>Stjn 0 fix Scribunto text/plain -- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('strict') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLanguage() -- Define constants local CONFIG_MODULE = 'Module:Message box/configuration' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Категория:%s|%s]]', cat, sort) else cat = string.format('[[Категория:%s]]', cat) end self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id self.name = args.name if self.name then self:addClass('mbox-' .. string.gsub(self.name,' ','_')) end if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs self.dataLabel1 = args['data-label-1'] self.dataLabel2 = args['data-label-2'] self.dataLabel3 = args['data-label-3'] self.dataValue1 = args['data-value-1'] self.dataValue2 = args['data-value-2'] self.dataValue3 = args['data-value-3'] -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then self.name = args.name if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName) self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else if args.sect and args.sect ~= '' or nil then local issue_sect = args.issue_sect issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil local text_sect = args.text_sect text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil local issues = {} table.insert(issues, issue_sect) table.insert(issues, text_sect) self.issue = table.concat(issues, ' ') else local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText = 'Соответствующую дискуссию можно найти на' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s [[%s#%s|странице обсуждения]].', talkText, talkTitle.prefixedText, talk ) end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then local status, result = pcall(formatDate, args.date) if status then date = string.format("(<span class='date'>%s</span>)", result) else date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date) end elseif args.date == '' and self.isTemplatePage then date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет end if date then self.date = string.format(" <span class='mbox-date'>''%s''</span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end if args.shortFix then self.shortFix = args.shortFix end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text self.textsmall = args['text-small'] end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell if cfg.imageEmptyCellStyle then self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' end -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= '' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or cfg.imageSize or '40x40px' self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end -- set templatestyles self.base_templatestyles = cfg.templatestyles end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg local date = nil if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local status, result = pcall(formatDate, args.date, 'xg Y') if status then date = result end date = type(date) == 'string' and date local preposition = 'с' local suffix = 'года' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix) self:addCat(0, catTitle) catTitle = getTitleObject('Категория:' .. catTitle) local status, result = pcall(formatDate, args.date) if not status then self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort) end if self.isSubstituted then self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами') end if self.isSmall then self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return categoryHandler{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end -- Conditional TemplateStyles loading if self.base_templatestyles then local frame = mw.getCurrentFrame() root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.base_templatestyles }, }) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.dataLabel1 then boxTable:attr('data-' .. self.dataLabel1, self.dataValue1) end if self.dataLabel2 then boxTable:attr('data-' .. self.dataLabel2, self.dataValue2) end if self.dataLabel3 then boxTable:attr('data-' .. self.dataLabel3, self.dataValue3) end if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):css('width', '52px') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') :cssText(self.imageEmptyCellStyle or nil) end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-div') :wikitext(self.issue or nil) local textsmallCellDiv = textCell:tag('div') textsmallCellDiv :addClass('mbox-textsmall-div hide-when-compact') :cssText(self.textsmallstyle) :wikitext(self.textsmall or nil) if (self.talk or self.fix) and not self.isSmall then textsmallCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.fix and (' ' .. self.fix) or nil) :wikitext(self.talk and (' ' .. self.talk) or nil) end if self.textsmall or self.fix or self.talk then textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil) else textCellDiv:wikitext(self.date and (' ' .. self.date) or nil) end if self.info and not self.isSmall then textsmallCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textsmallCellDiv:tag('small') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end if self.shortFix then textCell:tag('div') :addClass('mbox-multiply') :tag('span') :wikitext(string.format("%s", self.shortFix)) :tag('span') :wikitext(self.date and (' ' .. self.date) or nil) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):css('width', '52px') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :css('text-align', 'center') :wikitext(string.format( 'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f2539b657a9cdadde7c0dd5ad270d3095b2bdd54 Шаблон:Очистить кэш 10 61 132 2024-03-27T11:58:48Z wikipedia, ruwikipedia>Stjn 0 не помещать на все страницы ежедневную очистку кэша wikitext text/x-wiki <!-- Класс purgelink и атрибут data-pagename используются в [[MediaWiki:Common.js]], чтобы очищать кэш без перехода на отдельную страницу --><span class="noprint purgelink" {{#if: {{{2|}}} | data-pagename="{{{2}}}" }}>{{выполнить скрипт|purgeLink}}[[Special:Purge/{{#if: {{{2|}}} | {{{2}}} | {{FULLPAGENAME}} }}|{{#if: {{{1|}}} | {{{1}}} | Очистить кэш }}]]</span>{{#ifeq: {{NAMESPACE}}{{{nocat|}}} | {{ns:10}} <!-- Шаблон --> | {{очищать кэш|ежедневно}} }}<noinclude>{{doc}}</noinclude> be6695060ca61d2125386d02d3a19109c0e7c27b Модуль:Yesno 828 13 36 2024-03-30T22:30:54Z wikipedia, ruwikipedia>Stjn 0 кириллическая у из-за невозможности различить от латинской Scribunto text/plain -- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val == 'true' or val == 't' or val == 'да' or val == 'д' -- кириллица or val == 'у' or val == '+' or tonumber(val) == 1 then return true elseif val == false or val == 'no' or val == 'n' or val == 'false' or val == 'f' or val == 'нет' or val == 'н' or val == '-' or tonumber(val) == 0 then return false else return default end end ae94e12a838e770797317ed07b57b330ffeb7658 Шаблон:Yesno-yes 10 36 82 2024-04-05T13:04:36Z wikipedia, ruwikipedia>Stjn 0 подстановка wikitext text/x-wiki {{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude> {{doc}} </noinclude> 3792ff694708f98102e3a6d556abe73bedc29069 Шаблон:Выполнить скрипт 10 66 142 2024-04-07T13:34:28Z wikipedia, ruwikipedia>Stjn 0 отключение старой схемы wikitext text/x-wiki {{#switch: {{{1|}}} | = | mainPage = [[Категория:Википедия:Заглавная страница|{{NAMESPACENUMBER}}]] | #default = {{#ifexist: Категория:Википедия:Страницы с гаджетом по требованию {{{1}}} | [[Категория:Википедия:Страницы с гаджетом по требованию {{{1}}}|{{NAMESPACENUMBER}}]] }} }}<noinclude> {{doc}} </noinclude> 6979ea0342067dc76b9adcb9a5e072207c2c5a63 Шаблон:СИШ 10 69 148 2024-04-07T23:07:09Z wikipedia, ruwikipedia>Stjn 0 режет глаз wikitext text/x-wiki <noinclude>{{к объединению|2020-11-10|Шаблон:High-use}} </noinclude>{{ombox |type = notice |image = [[Файл:Stalewarning.svg|40px|alt=Время]] |text = '''Внимание! Это один из [[Special:MostLinkedTemplates|самых используемых {{#ifeq: {{NAMESPACENUMBER}} | 828 | модулей | шаблонов }}]].''' |text-small = Каждое его изменение создаёт [[mw:Manual:Job queue/ru|дополнительную нагрузку]] на сервера проекта. Пожалуйста, убедитесь в адекватности и правильности ваших изменений, проверьте их на тестовых страницах.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений]. }}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Шаблоны:С более чем 100 тысячами использований]]}}</includeonly><noinclude> {{doc}} </noinclude> 013201ef8d4ba8e3d1eb0dbba9c331a3d4ae519b Шаблон:Replace 10 30 70 2024-04-14T07:24:11Z wikipedia, ruwikipedia>Stjn 0 обновление аналогично английскому шаблону wikitext text/x-wiki {{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude> {{doc}} </noinclude> 7752c3c70ae8c46a89a0808aa282956866dbba5b Шаблон:Начало скрытого блока 10 43 96 2024-04-15T20:10:25Z wikipedia, ruwikipedia>Stjn 0 см. [[phab:T185674#9715417]] wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!-- --><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!-- --><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!-- -->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!-- -->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!-- --><div class="mw-collapsible-toggle-placeholder"></div></div><!-- --><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!-- -->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!-- --></includeonly><noinclude> {{doc}} </noinclude> 3b96bb802b522e629c41cddc5d44dfb2a9eb462a Модуль:Demo 828 103 216 2024-05-02T11:40:03Z wikipedia, ruwikipedia>Vavilexxx 0 исправление Scribunto text/plain local p = {} local getArgs = require('Модуль:Arguments').getArgs local function hasValue(param) if param and param:find('%S') then return true end end --creates a frame object that cannot access any of the parent's args --unless a table containing a list keys of not to inherit is provided function disinherit(frame, onlyTheseKeys) local parent = frame:getParent() or frame local orphan = parent:newChild{} orphan.getParent = parent.getParent --returns nil orphan.args = {} if onlyTheseKeys then local family = {parent, frame} for f = 1, 2 do for k, v in pairs(family[f] and family[f].args or {}) do orphan.args[k] = orphan.args[k] or v end end parent.args = mw.clone(orphan.args) setmetatable(orphan.args, nil) for _, k in ipairs(onlyTheseKeys) do rawset(orphan.args, k, nil) end end return orphan, parent end function p.get(frame, arg, passArgs) local orphan, frame = disinherit(frame, passArgs and {arg or 1}) local code, noWiki, preserve = frame.args[arg or 1] or '' local kill_categories = not frame.args.save_categories local tag, sep if code:match'nowiki' then local placeholder, preserve = ('6'):char(), {} -- We replace "&#125;%-" and "%-&#123;" because of some server bug probably connected to -- [[mw:Parsoid/MediaWiki DOM spec/Language conversion blocks]] and leading to -- =mw.text.unstripNoWiki(mw.getCurrentFrame():preprocess('<nowiki>}-</nowiki>')) -- outputting '&#125;-' instead of "}-", while it's ok with "<nowiki>} -</nowiki>" code = mw.text.unstripNoWiki(code) :gsub('&lt;', '<') :gsub('&gt;', '>') :gsub('&#125;%-', '}-') :gsub('%-&#123;', '-{') if (mw.text.trim(code):match'\n') then tag = 'pre' sep = '' end noWiki = code:gsub('%%', placeholder) for k in noWiki:gmatch('&.-;') do table.insert(preserve, (k:gsub('&', '&amp;'))) noWiki = noWiki:gsub('(&.-;)', '%%%s') end noWiki = mw.text.nowiki(noWiki):format(unpack(preserve)):gsub(placeholder, '%%') end return { source = noWiki or code, output = orphan:preprocess(code) :gsub(kill_categories and '%[%[Категория:.-%]%]' or '', '') :gsub(kill_categories and '%[%[К:.-%]%]' or '', '') :gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''), frame = frame, args = getArgs(frame), tag = tag, sep = sep } end function p.main(frame, demoTable) local show = demoTable or p.get(frame) local args = show.args local yesno = require('Module:Yesno') args.reverse = yesno(args.reverse, false) args.tag = hasValue(args.tag) and args.tag or hasValue(show.tag) and show.tag or "code" args.sep = args.sep or args.br or show.sep args.sep = tonumber(args.sep) and ('<br>'):rep(args.sep or 0) or args.sep or (args.tag == 'pre' and '' or ' → ') if show[args.result_arg] then return show[args.result_arg] end return args.reverse and string.format( '%s%s<%s%s%s>%s</%s>', show.output, args.sep, args.tag, hasValue(args.class) and string.format(' class="%s"', args.class) or '', hasValue(args.style) and string.format(' style="%s"', args.style) or '', show.source, args.tag ) or string.format( '<%s%s%s>%s</%s>%s%s', args.tag, hasValue(args.class) and string.format(' class="%s"', args.class) or '', hasValue(args.style) and string.format(' style="%s"', args.style) or '', show.source, args.tag, args.sep, show.output ) end --passing of args into other module without preprocessing function p.module(frame) local orphan, frame = disinherit(frame, { 'demo_template', 'demo_module', 'demo_module_func', 'demo_main', 'demo_br', 'demo_result_arg', 'demo_save_categories' }) local template = frame.args.demo_template and 'Template:'..frame.args.demo_template local demoFunc = frame.args.demo_module_func or 'main\n' local demoModule = require('Module:' .. frame.args.demo_module)[demoFunc:match('^%s*(.-)%s*$')] frame.args.br, frame.args.result_arg = frame.args.demo_br or frame.args.demo_sep, frame.args.demo_result_arg local kill_categories = not save_categories if demoModule then local named = {insert = function(self, ...) table.insert(self, ...) return self end} local source = {insert = named.insert, '{{', frame.args.demo_template or frame.args.demo_module, '\n'} if not template then source:insert(2, '#invoke:'):insert(4, '|'):insert(5, demoFunc) end local insertNamed = #source + 1 for k, v in pairs(orphan.args) do local nan, insert = type(k) ~= 'number', {v} local target = nan and named or source target:insert'|' if nan then target:insert(k):insert'=':insert'\n' table.insert(insert, 1, #target) end target:insert(unpack(insert)) local nowiki = v:match('nowiki') if nowiki or v:match('{{.-}}') then orphan.args[k] = frame:preprocess(nowiki and mw.text.unstripNoWiki(v) or v) end end source:insert'}}' table.insert(source, insertNamed, table.concat(named)) return p.main(orphan, { source = mw.text.encode(table.concat(source), "<>'|=~"), output = tostring(demoModule(orphan)):gsub(kill_categories and '%[%[Категория:.-%]%]' or '', ''):gsub(kill_categories and '%[%[К:.-%]%]' or '', ''):gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''), frame = frame }) else return "ERROR: Invalid module function: "..demoFunc end end return p 9beaf8f8041a39ae73ba17b2f70609171c4196d3 Шаблон:Действия для страницы/styles.css 10 57 124 2024-05-02T17:22:30Z wikipedia, ruwikipedia>Stjn 0 fix text text/plain .ts-tlinks-tlinks { font-weight: normal; float: right; line-height: inherit; } .ts-tlinks-tlinks .mw-editsection-divider { display: inline; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ a003e896d263c29e66d2246b210e5d73e577ea46 Шаблон:Действия для страницы 10 56 122 2024-05-02T17:24:27Z wikipedia, ruwikipedia>Stjn 0 никаких пиксельных fontsize wikitext text/x-wiki <templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!-- -->{{join|separator=<span class="mw-editsection-divider"> &amp;#124; </span> |1={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }} }} |2={{#ifexist: {{#rel2abs: {{{lc|}}} }} | [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]] }} |3={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }} }} |4={{#ifexist: {{#rel2abs: {{{lc|}}} }} | | [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать] }} |5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }} |6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }} }}<span class="mw-editsection-bracket">]</span></div><noinclude> {{doc}} </noinclude> 9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4 Шаблон:OnLua 10 64 138 2024-05-07T19:08:37Z wikipedia, ruwikipedia>MBH 0 MBH переименовал страницу [[Шаблон:OnLua]] в [[Шаблон:Lua]] wikitext text/x-wiki #перенаправление [[Шаблон:Lua]] b72371e7ae22239863c474a78238171c2bd94c7e Шаблон:Lua 10 71 152 2024-05-07T19:08:37Z wikipedia, ruwikipedia>MBH 0 MBH переименовал страницу [[Шаблон:OnLua]] в [[Шаблон:Lua]] wikitext text/x-wiki <includeonly>{{ombox | small = yes | style = width:23em; | image = [[Файл:Lua-logo-nolabel.svg|40px|alt=|link=]] | text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|&#58;<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}|&#32;с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из&#32;}}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!-- -->{{#invoke:Transclude|npc|OnLua/Строка| module= |function= |tech= |line= }}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}} }}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}</noinclude> f1fdaa87edb15d61e23e98f6e25d171a975e10eb Шаблон:OnLua/Строка 10 67 144 2024-05-07T19:08:38Z wikipedia, ruwikipedia>MBH 0 MBH переименовал страницу [[Шаблон:OnLua/Строка]] в [[Шаблон:Lua/Строка]] wikitext text/x-wiki #перенаправление [[Шаблон:Lua/Строка]] d7f869ccc7a7efc800399fce32bc75e0f91066de Шаблон:Lua/Строка 10 74 158 2024-05-07T19:08:38Z wikipedia, ruwikipedia>MBH 0 MBH переименовал страницу [[Шаблон:OnLua/Строка]] в [[Шаблон:Lua/Строка]] wikitext text/x-wiki <includeonly>{{#if: {{{module|}}}{{{tech|}}} | <li>с использованием {{#if: {{{tech|}}} | {{{tech}}} | {{#if: {{{function|}}} | {{#if: {{{module|}}} | функции <code>{{#if: {{{line|}}} | [{{fullurl: Module:{{{module}}}|action=edit}}#mw-ce-l{{{line}}} {{{function}}}()] | [[{{{funcref|Module:{{{module}}}#{{{function}}}}}} | {{{function}}}()]]}}</code> из&#32;}}}}{{#if: {{{module|}}} | модуля [[Module:{{{module}}} | {{{module}}}]]}}}};}}</includeonly><noinclude>[[Категория:Шаблоны:Подстраницы шаблонов]]</noinclude> 5a35837338c2daee2d240a8e5335e8fec8e7d87e Шаблон:Дерево категорий 10 68 146 2024-05-17T22:35:29Z wikipedia, ruwikipedia>QBA-bot 0 Защитил страницу [[Шаблон:Дерево категорий]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki <div>{{{title|'''Дерево категорий'''}}} {{#tag: categorytree| {{#if:{{{1|}}}|{{{1}}}|{{PAGENAME}}}} | mode = {{#if:{{{2}}}|"{{#ifeq:{{{2}}}|всё|all|{{#ifeq:{{{2}}}|страницы|pages|{{#ifeq:{{{2}}}|категории|categories|{{{2}}}}}}}}}"}} | depth = {{#if:{{{3}}}|{{{3}}}}} }} </div><noinclude> {{doc}} </noinclude> 9763d532ff7b79a638abe485875db984254b57db Модуль:Sources 828 83 176 2024-06-10T20:41:59Z wikipedia, ruwikipedia>Stjn 0 возврат, сломало [[Википедия:Форум/Технический#Ошибка lua]] Scribunto text/plain ---@alias args table ---@alias frame { args: args, extensionTag: function, newChild: ( fun( args: args ): frame ) } ---@alias source { publication: source, [string]: any } ---@alias value: string | { id: string } ---@alias snak { datatype: string, snaktype: string, datavalue: { type: string, value: value } } ---@alias snaks table<string, table<number, snak>> ---@alias statement { mainsnak: snak, rank: string, qualifiers: snaks } ---@alias statements table<string, table<number, statement>> ---@alias map { name: string, ids: string[] }[]> ---@type table local p = {} ---@type table<string, string> local NORMATIVE_DOCUMENTS = { Q20754888 = 'Закон Российской Федерации', Q20754884 = 'Закон РСФСР', Q20873831 = 'Распоряжение Президента Российской Федерации', Q20873834 = 'Указ исполняющего обязанности Президента Российской Федерации', Q2061228 = 'Указ Президента Российской Федерации', } ---@type table<string, string> local LANG_CACHE = { Q150 = 'fr', Q188 = 'de', Q1321 = 'es', Q1860 = 'en', Q652 = 'it', Q7737 = 'ru', Q8798 = 'uk', } ---@type map local PROPERTY_MAP = { { name = 'sourceId', ids = { 'P248', 'P805' } }, { name = 'lang', ids = { 'P407', 'P364' } }, { name = 'author', ids = { 'P50', 'P2093' } }, { name = 'part', ids = { 'P958', 'P1810' } }, { name = 'title', ids = { 'P1476' } }, { name = 'subtitle', ids = { 'P1680' } }, { name = 'url', ids = { 'P953', 'P1065', 'P854', 'P973', 'P2699', 'P888' } }, { name = 'editor', ids = { 'P98' } }, { name = 'translator', ids = { 'P655' } }, { name = 'publication-id', ids = { 'P1433' } }, { name = 'edition', ids = { 'P393' } }, { name = 'publisher', ids = { 'P123' } }, { name = 'place', ids = { 'P291' } }, { name = 'volume', ids = { 'P478' } }, { name = 'issue', ids = { 'P433' } }, { name = 'dateOfCreation', ids = { 'P571' } }, { name = 'dateOfPublication', ids = { 'P577' } }, { name = 'pages', ids = { 'P304' } }, { name = 'numberOfPages', ids = { 'P1104' } }, { name = 'tirage', ids = { 'P1092' } }, { name = 'isbn', ids = { 'P212', 'P957' } }, { name = 'issn', ids = { 'P236' } }, -- { name = 'accessdate', ids = { 'P813' } }, -- disable, creates duplicate references { name = 'docNumber', ids = { 'P1545' } }, { name = 'type', ids = { 'P31' } }, { name = 'arxiv', ids = { 'P818' } }, { name = 'doi', ids = { 'P356' } }, { name = 'pmid', ids = { 'P698' } }, } -- table.insert( PROPERTY_MAP.url, 'P856' ) -- only as qualifier ---@type map local PUBLICATION_PROPERTY_MAP = mw.clone( PROPERTY_MAP ) ---@type string[] local monthGen = { 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' } ---@type string local i18nDefaultLanguage = mw.language.getContentLanguage():getCode() p.i18nDefaultLanguage = i18nDefaultLanguage ---@type string local i18nEtAlDefault = ' et al.' ---@type table<string, string> local i18nEtAl = { ru = ' и др.', uk = ' та ін.', } ---@type table<string, string> local i18nEditors = { fr = '', de = 'Hrsg.: ', es = '', en = '', it = '', ru = 'под ред. ', uk = 'за ред. ', } ---@type table<string, string> local i18nTranslators = { fr = '', de = '', es = '', en = '', it = '', ru = 'пер. ', uk = 'пер. ', } ---@type table<string, string> local i18nVolume = { de = 'Vol.', fr = 'Vol.', es = 'Vol.', en = 'Vol.', it = 'Vol.', ru = 'Т.', uk = 'Т.', } ---@type table<string, string> local i18nIssue = { en = 'Iss.', ru = 'вып.', uk = 'вип.', } ---@type table<string, string> local i18nPages = { fr = 'P.', de = 'S.', es = 'P.', en = 'P.', it = 'P.', ru = 'С.', uk = 'С.', } ---@type table<string, string> local i18nNumberOfPages = { en = 'p.', ru = 'с.', } ---@type table<string, string> local i18nTirage = { en = 'ed. size: %d', ru = '%d экз.', } ---@param args args ---@return source local function getFilledArgs( args ) ---@type source local data = {} for key, value in pairs( args ) do if mw.text.trim( value ) ~= '' then if key == 1 then key = 'sourceId' end data[ key ] = mw.text.trim( value ) end end return data end ---Returns formatted pair {Family name(s), First name(s)} ---@param fullName string ---@return table<number, string> local function tokenizeName( fullName ) local space = '%s+' -- matches single or more spacing character local name = "(%a[%a%-']*)%.?" -- matches single name, have to start with letter, can contain apostrophe and hyphen, may end with dot local surname = "(%a[%a%-']*)" -- same as name, but can't end with dot local surnamePrefixes = { 'ван', 'van', 'де', 'de' } local nm, nm2, srn, srn2, pref fullName = ' ' .. fullName .. ' ' fullName = mw.ustring.gsub( fullName, ' оглы ', ' ' ) fullName = mw.text.trim( fullName ) -- Surname, Name local pattern = '^' .. surname .. ',' .. space .. name .. '$' srn, nm = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.' } end -- Surname, Name prefix for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. surname .. ',' .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$' srn, nm, pref = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.' } end end -- Surname, Name Name pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. '$' srn, nm, nm2 = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end -- Surname Surname, Name pattern = '^' .. surname .. space .. surname .. ',' .. space .. name .. '$' srn, srn2, nm = mw.ustring.match( fullName, pattern ) if srn then return { srn .. '&nbsp;' .. srn2, mw.ustring.sub( nm, 1, 1 ) .. '.' } end -- Name Name Surname pattern = '^' .. name .. space .. name .. space .. surname .. '$' nm, nm2, srn = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end -- Name Name prefix Surname for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. space .. surname .. '$' nm, nm2, pref, srn = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end end -- Surname, Name Name prefix for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$' srn, nm, nm2, pref = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end end -- Name{1,4} Surname for k = 1, 4 do pattern = '^' .. string.rep( name .. space, k ) .. surname .. '$' ---@type string[] local matched = { mw.ustring.match( fullName, pattern ) } if #matched ~= 0 then for j = 1, k do matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 ) end return { matched[ k + 1 ], table.concat( matched, '.&nbsp;', 1, k ) .. '.' } end end -- Surname Name{1,4} for k = 1, 4 do pattern = '^' .. surname .. string.rep( space .. name, k ) .. '$' ---@type string[] local matched = { mw.ustring.match( fullName, pattern ) } if #matched ~= 0 then for j = 2, k + 1 do matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 ) end return { matched[ 1 ], table.concat( matched, '.&nbsp;', 2, k + 1 ) .. '.' } end end return { fullName } end ---@param fullName string | nil ---@return string | nil local function personNameToAuthorName( fullName ) if not fullName then return nil end local tokenized = tokenizeName( fullName ) if #tokenized == 1 then return tokenized[ 1 ] end return tokenized[ 1 ] .. '&nbsp;' .. tokenized[ 2 ] end ---@param fullName string | nil ---@return string | nil local function personNameToResponsibleName( fullName ) if not fullName then return nil end local tokenized = tokenizeName( fullName ) if #tokenized == 1 then return tokenized[ 1 ] end return tokenized[ 2 ] .. '&nbsp;' .. tokenized[ 1 ] end ---@alias options { separator: string, conjunction: string, format: ( fun( data: string ): string ), nolinks: boolean, preferids: boolean, short: boolean } ---@type options local options_commas = { separator = ', ', conjunction = ', ', format = function( data ) return data end, nolinks = false, preferids = false, short = false, } ---@type options local options_commas_short = mw.clone( options_commas ) options_commas_short.short = true ---@type options local options_commas_it_short = mw.clone( options_commas_short ) options_commas_it_short.format = function( data ) return "''" .. data .. "''" end ---@type options local options_commas_nolinks = mw.clone( options_commas ) options_commas_nolinks.nolinks = true ---@type options local options_citetypes = { separator = ' ', conjunction = ' ', format = function( data ) return 'citetype_' .. data end, nolinks = true , preferids = true, short = false, } ---@type options local options_commas_authors = mw.clone( options_commas ) options_commas_authors.format = personNameToAuthorName ---@type options local options_commas_responsible = mw.clone( options_commas ) options_commas_responsible.format = personNameToResponsibleName ---@type options local options_ids = { separator = '; ', conjunction = '; ', format = function( id ) return id end, nolinks = true, preferids = false, short = false, } ---@type options local options_arxiv = mw.clone( options_ids ) options_arxiv.format = function( id ) return '[https://arxiv.org/abs/' .. id .. ' arXiv:' .. id .. ']' end ---@type options local options_doi = mw.clone( options_ids ) options_doi.format = function( doi ) return '[https://dx.doi.org/' .. doi .. ' doi:' .. doi .. ']' end ---@type options local options_issn = mw.clone( options_ids ) options_issn.format = function( issn ) return '[https://www.worldcat.org/issn/' .. issn .. ' ' .. issn .. ']' end ---@type options local options_pmid = mw.clone( options_ids ) options_pmid.format = function( pmid ) return '[https://www.ncbi.nlm.nih.gov/pubmed/?term=' .. pmid .. ' PMID:' .. pmid .. ']' end ---@param str string | nil ---@return boolean local function isEmpty( str ) return not str or #str == 0 end ---@param allQualifiers snaks ---@param qualifierPropertyId string ---@return string | nil local function getSingleStringQualifierValue( allQualifiers, qualifierPropertyId ) if not allQualifiers or not allQualifiers[ qualifierPropertyId ] then return nil end ---@type table<number, snak> local propertyQualifiers = allQualifiers[ qualifierPropertyId ] for _, qualifier in pairs( propertyQualifiers ) do if ( qualifier and qualifier.datatype == 'string' and qualifier.datavalue and qualifier.datavalue.type == 'string' and qualifier.datavalue.value ~= '' ) then return qualifier.datavalue.value end end return nil end ---@param data table ---@param resultProperty string ---@return void local function appendImpl_toTable( data, resultProperty ) if not data[ resultProperty ] then data[ resultProperty ] = {} elseif ( type( data[ resultProperty ] ) == 'string' or ( type( data[ resultProperty ] ) == 'table' and type( data[ resultProperty ].id ) == 'string' ) ) then data[ resultProperty ] = { data[ resultProperty ] } end end ---@param datavalue table ---@param qualifiers snaks ---@param data table ---@param propertyName string ---@param options table local function appendImpl( datavalue, qualifiers, data, propertyName, options ) data[ propertyName ] = data[ propertyName ] or {} if propertyName == 'issn' then table.insert( data[ propertyName ], datavalue.value ) elseif propertyName == 'url' or datavalue.type == 'url' then local value = datavalue.value if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'string' then local value = getSingleStringQualifierValue( qualifiers, 'P1932' ) if not value then value = getSingleStringQualifierValue( qualifiers, 'P1810' ) end if not value then value = datavalue.value if options.format then value = options.format( value ) end end appendImpl_toTable(data, propertyName) local pos = getSingleStringQualifierValue( qualifiers, 'P1545' ) if pos then table.insert( data[ propertyName ], tonumber(pos), value ) else table.insert( data[ propertyName ], value ) end elseif datavalue.type == 'monolingualtext' then local value = datavalue.value.text if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'quantity' then local value = datavalue.value.amount if ( mw.ustring.sub( value , 1, 1 ) == '+' ) then value = mw.ustring.sub( value , 2 ) end if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'wikibase-entityid' then local pos = getSingleStringQualifierValue( qualifiers, 'P1545' ) local value = datavalue.value appendImpl_toTable(data, propertyName) local label = getSingleStringQualifierValue( qualifiers, 'P1932' ) if not label then label = getSingleStringQualifierValue( qualifiers, 'P1810' ) end local toInsert = { id = value.id, label = label } if pos and tonumber( pos ) then table.insert( data[ propertyName ], tonumber( pos ), toInsert ) else table.insert( data[ propertyName ], toInsert ) end elseif datavalue.type == 'time' then local value = datavalue.value if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], tostring( value.time ) ) end end ---@param entityId string ---@param propertyId string ---@return table<number, statement> local function getAllStatements( entityId, propertyId ) ---@type boolean, table<number, statement> local wdStatus, statements = pcall( mw.wikibase.getAllStatements, entityId, propertyId ) if wdStatus and statements then return statements end return {} end ---@param entityId string ---@param propertyId string ---@return table<number, statement> local function getBestStatements( entityId, propertyId ) ---@type boolean, table<number, statement> local wdStatus, statements = pcall( mw.wikibase.getBestStatements, entityId, propertyId ) if wdStatus and statements then return statements end return {} end ---@param entityId string ---@param projectToCheck string? ---@return string | nil local function getSitelink( entityId, projectToCheck ) ---@type boolean, string local wbStatus, sitelink if projectToCheck then wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId, projectToCheck ) else wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId ) end if not wbStatus then return nil end return sitelink end ---@param args any[] ---@return any | nil local function coalesce( args ) for _, arg in pairs( args ) do if not isEmpty( arg ) then return arg end end return nil end ---@param value any ---@return string | nil local function getSingle( value ) if type( value ) == 'string' then return tostring( value ) elseif type( value ) == 'table' then if value.id then return tostring( value.id ) end for _, tableValue in pairs( value ) do return getSingle( tableValue ) end end return nil end ---@param langEntityId string ---@return string | nil local function getLangCode( langEntityId ) if not langEntityId then return nil end langEntityId = getSingle( langEntityId ) if not string.match( langEntityId, '^Q%d+$' ) then return langEntityId end local cached = LANG_CACHE[ langEntityId ] if cached then if cached == '' then return nil end return cached end local claims = getBestStatements( langEntityId, 'P424' ) for _, claim in pairs( claims ) do if claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value then LANG_CACHE[ langEntityId ] = claim.mainsnak.datavalue.value return claim.mainsnak.datavalue.value end end LANG_CACHE[ langEntityId ] = '' return nil end ---@param entityId string ---@param propertyId string ---@param data source ---@param propertyName string ---@param options table? ---@return void local function appendEntitySnaks( entityId, propertyId, data, propertyName, options ) options = options or {} -- do not populate twice if data[ propertyName ] and ( propertyName ~= 'author' or data[ propertyId ] ) then return end local statements = getBestStatements( entityId, propertyId ) if propertyName == 'author' then data[ propertyId ] = true end local lang = getLangCode( data.lang ) or i18nDefaultLanguage if propertyId == 'P1680' then -- if there is a default language for _, statement in pairs( statements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value and statement.mainsnak.datavalue.value.language == lang then --found default language string appendImpl( statement.mainsnak.datavalue, statement.qualifiers, data, propertyName, options ) return end end end for _, statement in pairs( statements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue then appendImpl( statement.mainsnak.datavalue, statement.qualifiers or {}, data, propertyName, options ) if propertyName == 'publication-id' and statement.qualifiers then data[ 'publication-qualifiers' ] = statement.qualifiers end end end end ---@param claims table<number, statement> ---@param qualifierPropertyId string ---@param result table ---@param resultPropertyId string ---@param options table ---@return void local function appendQualifiers( claims, qualifierPropertyId, result, resultPropertyId, options ) -- do not populate twice if not claims or result[ resultPropertyId ] then return end for _, claim in pairs( claims ) do if claim.qualifiers and claim.qualifiers[ qualifierPropertyId ] then ---@type table<number, snak> local propertyQualifiers = claim.qualifiers[ qualifierPropertyId ] for _, qualifier in pairs( propertyQualifiers ) do if qualifier and qualifier.datavalue then appendImpl( qualifier.datavalue, nil, result, resultPropertyId, options ) end end end end end ---@param entityId string ---@param propertyId string ---@param value any ---@return table<number, statement> local function findClaimsByValue( entityId, propertyId, value ) local result = {} local claims = getAllStatements( entityId, propertyId ) for _, claim in pairs( claims ) do if ( claim.mainsnak and claim.mainsnak.datavalue ) then local datavalue = claim.mainsnak.datavalue if ( datavalue.type == "string" and datavalue.value == value ) or ( datavalue.type == "wikibase-entityid" and datavalue.value[ "entity-type" ] == "item" and tostring( datavalue.value.id ) == value ) then table.insert( result, claim ) end end end return result end ---@param entityId string ---@param typeEntityId string ---@return boolean local function isInstanceOf( entityId, typeEntityId ) return findClaimsByValue( entityId, 'P31', typeEntityId )[ 1 ] ~= nil end ---@param entityId string ---@param typeEntityIds string[] ---@return string ---@todo Rewrite local function getFirstType( entityId, typeEntityIds ) for _, typeEntityId in pairs( typeEntityIds ) do if isInstanceOf( entityId, typeEntityId ) then return typeEntityId end end return nil end ---@param snaks snaks ---@param data source ---@param map map ---@return void local function populateDataFromSnaks( snaks, data, map ) for _, row in ipairs( map ) do local parameterName, propertyIds = row.name, row.ids for _, propertyId in pairs( propertyIds ) do if not data[ parameterName ] and snaks[ propertyId ] then local options = {} if propertyId == 'P888' then options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end } end for _, snak in pairs( snaks[ propertyId ] ) do if snak and snak.datavalue then appendImpl( snak.datavalue, {}, data, parameterName, options ) end end end end end end ---@param entityId string | nil ---@param data source ---@param map map ---@return void local function populateDataFromEntity( entityId, data, map ) if not data.title then if not isEmpty( entityId ) then local optionsAsLinks = { format = function( text ) return { id = entityId, label = text } end } appendEntitySnaks( entityId, 'P1476', data, 'title', optionsAsLinks ) else appendEntitySnaks( entityId, 'P1476', data, 'title', {} ) end appendEntitySnaks( entityId, 'P1680', data, 'subtitle', {} ) end local bookSeriesStatements = getBestStatements( entityId, 'P361' ) for _, statement in pairs( bookSeriesStatements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value and statement.mainsnak.datavalue.value.id then local possibleBookSeriesEntityId = statement.mainsnak.datavalue.value.id if isInstanceOf( possibleBookSeriesEntityId, 'Q277759' ) then appendImpl_toTable( data, 'bookSeries' ) table.insert( data.bookSeries, { id = possibleBookSeriesEntityId } ) appendQualifiers( { statement }, 'P478', data, 'bookSeriesVolume', {} ) appendQualifiers( { statement }, 'P433', data, 'bookSeriesIssue', {} ) end end end for _, row in ipairs( map ) do local parameterName, propertyIds = row.name, row.ids for _, propertyId in pairs( propertyIds ) do local options = {} if propertyId == 'P888' then options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end } end appendEntitySnaks( entityId, propertyId, data, parameterName, options ) end end end ---@param data source ---@return void local function expandPublication( data ) if not data[ 'publication-id' ] then return end local publicationId = getSingle( data[ 'publication-id' ] ) data.publication = {} for key, value in pairs( data ) do if not string.match( key, '^publication-' ) then data.publication[ key ] = value end end data.publication.sourceId = publicationId data.publication.title = data[ 'publication-title' ] data.publication.subtitle = data[ 'publication-subtitle' ] if data[ 'publication-qualifiers' ] then populateDataFromSnaks( data[ 'publication-qualifiers' ], data.publication, PUBLICATION_PROPERTY_MAP ) end populateDataFromEntity( publicationId, data.publication, PUBLICATION_PROPERTY_MAP ) if type( data.publication.title ) == 'table' and data.publication.title[ 1 ] then data.publication.title = data.publication.title[ 1 ] end if type( data.publication.subtitle ) == 'table' and data.publication.subtitle[ 1 ] then data.publication.subtitle = data.publication.subtitle[ 1 ] end for key, value in pairs( data.publication ) do if key ~= 'sourceId' and key ~= 'title' and key ~= 'subtitle' and key ~= 'url' and not data[ key ] then data[ key ] = value end end end ---@param data source ---@return void local function expandBookSeries( data ) local bookSeries = data.bookSeries if not bookSeries then return end -- use only first one if type( bookSeries ) == 'table' and bookSeries[ 1 ] and bookSeries[ 1 ].id then data.bookSeries = bookSeries[ 1 ] bookSeries = data.bookSeries end if not bookSeries or not bookSeries.id then return end appendEntitySnaks( bookSeries.id, 'P123', data, 'publisher', {} ) appendEntitySnaks( bookSeries.id, 'P291', data, 'place', {} ) appendEntitySnaks( bookSeries.id, 'P236', data, 'issn', {} ) end ---@param entityId string ---@return string | nil local function getNormativeTitle( entityId ) local possibleTypeIds = {} for typeId, _ in pairs( NORMATIVE_DOCUMENTS ) do table.insert( possibleTypeIds, typeId ) end local foundTypeId = getFirstType( entityId, possibleTypeIds ) if foundTypeId then return NORMATIVE_DOCUMENTS[ foundTypeId ] end return nil end ---@param urls table<number, string> | string ---@param text string ---@return string local function wrapInUrl( urls, text ) local url = getSingle( urls ) if string.sub( url, 1, 1 ) == ':' then return '[[' .. url .. '|' .. text .. ']]' else return '[' .. url .. ' ' .. text .. ']' end end ---@param entityId string ---@param lang string ---@return string local function getElementLink( entityId, lang ) local sitelink = getSitelink( entityId, nil ) if sitelink then return ':' .. sitelink end if lang ~= 'mul' then -- link to entity in source language sitelink = getSitelink( entityId, lang .. 'wiki' ) if sitelink then return ':' .. lang .. ':' .. sitelink end end return ':d:' .. entityId end ---@param entityId string ---@param lang string ---@return string local function getLabel( entityId, lang ) local wbStatus, label = pcall( mw.wikibase.getLabelByLang, entityId, lang ) if not wbStatus then return '' end if label and label ~= '' then return label end wbStatus, label = pcall( mw.wikibase.getLabel, entityId ) if not wbStatus then return '' end return label or '' end ---@param lang string ---@param entityId string ---@param customTitle string ---@param options table local function renderLink( lang, entityId, customTitle, options ) if not entityId then error( 'entityId is not specified' ) end if type( entityId ) ~= 'string' then error( 'entityId is not string, but ' .. type( entityId ) ) end if type( customTitle or '' ) ~= 'string' then error( 'customTitle is not string, but ' .. type( customTitle ) ) end local title = customTitle -- ISO 4 if isEmpty( title ) then local propertyStatements = getBestStatements( entityId, 'P1160' ) for _, claim in pairs( propertyStatements ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == lang ) then title = claim.mainsnak.datavalue.value.text -- mw.log( 'Got title of ' .. entityId .. ' from ISO 4 claim: «' .. title .. '»' ) break end end end -- official name P1448 -- short name P1813 if isEmpty( title ) and options.short then local propertyStatements = getBestStatements( entityId, 'P1813' ) for _, claim in pairs( propertyStatements ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == lang ) then title = claim.mainsnak.datavalue.value.text -- mw.log( 'Got title of ' .. entityId .. ' from short name claim: «' .. title .. '» (' .. lang .. ')' ) break end end end -- person name P1559 -- labels if isEmpty( title ) then title = getLabel( entityId, lang ) -- mw.log( 'Got title of ' .. entityId .. ' from label: «' .. title .. '» (' .. lang .. ')' ) end local actualText = title or '\'\'(untranslated)\'\'' local link = getElementLink( entityId, lang ) return wrapInUrl( link, actualText ) end ---@param lang string ---@param value value ---@param options options ---@return string local function asString( lang, value, options ) if type( value ) == 'string' then return options.format( value ) end if type( value ) ~= 'table' then return options.format( '(unknown type)' ) end if value.id then -- this is link if type( value.label or '' ) ~= 'string' then mw.logObject( value, 'error value' ) error( 'label of table value is not string but ' .. type( value.label ) ) end local title if options.preferids then title = value.id elseif options.nolinks then title = value.label or getLabel( value.id, lang ) else title = renderLink( lang, value.id, value.label, options ) end if title == '' then title = "''(untranslated title)''" end return options.format( title ) end local resultList = {} for _, tableValue in pairs( value ) do table.insert( resultList, asString( lang, tableValue, options ) ) end return mw.text.listToText( resultList, options.separator, options.conjunction ) end ---@param entityId string ---@param data source ---@return source local function populateSourceDataImpl( entityId, data, map ) local wsLink = getSitelink( entityId, 'ruwikisource' ) if wsLink and not mw.ustring.gmatch( wsLink, 'Категория:' ) then data.url = ":ru:s:" .. wsLink end populateDataFromEntity( entityId, data, map ) local normativeTitle = getNormativeTitle( entityId ) if normativeTitle then local y, m, d = mw.ustring.match( getSingle( data.dateOfCreation ) , "(%-?%d+)%-(%d+)%-(%d+)T" ) y, m, d = tonumber( y ),tonumber( m ), tonumber( d ) local title = asString( 'ru', data.title, options_commas_nolinks ) local docNumber = getSingle( data.docNumber ) data.title = { normativeTitle .. " от&nbsp;" .. tostring( d ) .. "&nbsp;" .. monthGen[ m ] .. " " .. tostring( y ) .. "&nbsp;г." .. ( docNumber and ( " №&nbsp;" .. docNumber ) or '' ) .. ' «' .. title.. '»' } end if not data.title then local lang = getLangCode( data.lang ) or i18nDefaultLanguage local label = getLabel( entityId, lang ) if label ~= '' then data.title = { label } end end return data end ---@param entityId string ---@param propertyId string ---@param data source ---@return void local function expandSpecialsQualifiers( entityId, propertyId, data ) local statements = getBestStatements( entityId, propertyId ) for _, statement in pairs( statements ) do populateDataFromSnaks( statement.qualifiers or {}, data, PROPERTY_MAP ) end end ---Expand special types of references when additional data could be found in OTHER entity properties ---@param data source ---@return void local function expandSpecials( data ) if not data.entityId then return end if data.sourceId == 'Q36578' then -- Gemeinsame Normdatei -- specified by P227 appendEntitySnaks( data.entityId, 'P227', data, 'part', { format = function(gnd ) return 'Record #' .. gnd; end } ) appendEntitySnaks( data.entityId, 'P227', data, 'url', { format = function(gnd ) return 'http://d-nb.info/gnd/' .. gnd .. '/'; end } ) data.year = '2012—2016' expandSpecialsQualifiers( data.entityId, 'P227', data ) elseif data.sourceId == 'Q15222191' then -- BNF -- specified by P268 appendEntitySnaks( data.entityId, 'P268', data, 'part', { format = function(id ) return 'Record #' .. id; end } ) appendEntitySnaks( data.entityId, 'P268', data, 'url', { format = function(id ) return 'http://catalogue.bnf.fr/ark:/12148/cb' .. id; end } ) expandSpecialsQualifiers( data.entityId, 'P268', data ) elseif data.sourceId == 'Q54919' then -- VIAF -- specified by P214 appendEntitySnaks( data.entityId, 'P214', data, 'part', { format = function(id ) return 'Record #' .. id; end } ) appendEntitySnaks( data.entityId, 'P214', data, 'url', { format = function(id ) return 'https://viaf.org/viaf/' .. id; end } ) expandSpecialsQualifiers( data.entityId, 'P214', data ) else -- generic property search for _, sourceClaim in pairs( getBestStatements( data.sourceId, 'P1687' ) ) do if sourceClaim.mainsnak.snaktype == 'value' then local sourcePropertyId = sourceClaim.mainsnak.datavalue.value.id for _, sourcePropertyClaim in pairs( getBestStatements( sourcePropertyId, 'P1630' ) ) do if sourcePropertyClaim.mainsnak.snaktype == 'value' then appendEntitySnaks( data.entityId, sourcePropertyId, data, 'url', { format = function( id ) return mw.ustring.gsub( mw.ustring.gsub( sourcePropertyClaim.mainsnak.datavalue.value, '$1', id ), ' ', '%%20' ) end } ) expandSpecialsQualifiers( data.entityId, sourcePropertyId, data ) break end end end end end -- do we have appropriate record in P1433 ? local claims = findClaimsByValue( currentEntityId, 'P1343', data.sourceId ) if claims and #claims ~= 0 then for _, claim in pairs( claims ) do populateDataFromSnaks( claim.qualifiers, data, PROPERTY_MAP ) populateDataFromEntity( data.sourceId, data, PROPERTY_MAP ) end end end ---@param text string ---@param tip string ---@return string local function toTextWithTip( text, tip ) return '<span title="' .. tip .. '" style="border-bottom: 1px dotted; cursor: help; white-space: nowrap">' .. text .. '</span>' end ---@param lang string ---@param placeId string ---@return string local function getPlaceName( placeId, lang ) -- ГОСТ Р 7.0.12—2011 if lang == 'ru' then if placeId == 'Q649' then return toTextWithTip( 'М.', 'Москва' ); end if placeId == 'Q656' then return toTextWithTip( 'СПб.', 'Санкт-Петербург' ); end if placeId == 'Q891' then return toTextWithTip( 'Н. Новгород', 'Нижний Новгород' ); end if placeId == 'Q908' then return toTextWithTip( 'Ростов н/Д.', 'Ростов-на-Дону' ); end end return nil end ---@param data source ---@param lang string ---@return void local function preprocessPlace( data, lang ) if not data.place then return end ---@type table<number, string> local newPlace = {} for index, place in pairs( data.place ) do if place.id then local newPlaceStr = getPlaceName( place.id, lang ) if newPlaceStr then newPlace[ index ] = newPlaceStr else newPlace[ index ] = getLabel( place.id, lang ) end else newPlace[ index ] = place end end data.place = newPlace end ---@param entityId string ---@param lang string ---@param providedLabel string | nil ---@param options options ---@return string local function getPersonNameAsLabel( entityId, lang, providedLabel, options ) -- would custom label provided we don't need to check entity at all if not isEmpty( providedLabel ) then return options.format( providedLabel ) end if lang == 'mul' then lang = i18nDefaultLanguage end ---@type string | nil local personName = getLabel( entityId, lang ) if isEmpty( personName ) then return '\'\'(not translated to ' .. lang .. ')\'\'' end if not isInstanceOf( entityId, 'Q5' ) then return personName end return options.format( personName ) end ---@param entityId string ---@param lang string ---@param customLabel string | nil ---@param options options ---@return string local function getPersonNameAsWikitext( entityId, lang, customLabel, options ) local personName = getPersonNameAsLabel( entityId, lang, customLabel, options ) local link = getElementLink( entityId, lang ) return wrapInUrl( link, personName ) end ---@param value value ---@param lang string ---@param options options ---@return string local function getPeopleAsWikitext( value, lang, options ) if type( value ) == 'string' then return options.format( value ) elseif type( value ) == 'table' then if value.id then -- this is link if options.preferids then return tostring( value.id ) else if options.nolinks then return getPersonNameAsLabel( value.id, lang, value.label, options ) else return getPersonNameAsWikitext( value.id, lang, value.label, options ) end end end local maxAuthors = 10 -- need some restrictions, as some publications have enormous amount of authors (e.g. 115 authors of Q68951544) local resultList = {} for _, tableValue in pairs( value ) do local nextWikitext = getPeopleAsWikitext( tableValue, lang, options ) if not isEmpty( nextWikitext ) then table.insert( resultList, nextWikitext ) if #resultList == maxAuthors + 1 then -- keep one more to indicate that there are too many break end end end local resultWikitext = '' for i, wikitext in pairs( resultList ) do if i == maxAuthors + 1 then resultWikitext = resultWikitext .. ( i18nEtAl[ lang ] or i18nEtAlDefault ) break end if i ~= 1 then resultWikitext = resultWikitext .. ', ' end resultWikitext = resultWikitext .. wikitext end return resultWikitext end return '' -- options.format( '(unknown type)' ) end ---@param lang string ---@param data source ---@return string local function generateAuthorLinks( lang, data ) local result = '' if data.author then result = getPeopleAsWikitext( data.author, lang, options_commas_authors ) result = '<i class="wef_low_priority_links">' .. result .. '</i> ' end return result end ---@param lang string ---@param data source ---@param conjunction string ---@param propertyName string ---@param urlPropertyName string? ---@return string local function appendProperty( lang, data, conjunction, propertyName, urlPropertyName ) if not data[ propertyName ] then return '' end local out if urlPropertyName and data[ urlPropertyName ] then out = wrapInUrl( data[ urlPropertyName ], asString( lang, data[ propertyName ], options_commas_nolinks ) ) else out = asString( lang, data[ propertyName ], options_commas ) end if not out or out == '' then return '' end return conjunction .. out end ---@param lang string ---@param data source ---@return string local function appendTitle( lang, data ) local conjunction = '' local result = '' if data.part then result = result .. appendProperty( lang, data, '', 'part', 'parturl' ) conjunction = ' // ' end return result .. appendProperty( lang, data, conjunction, 'title', 'url' ) end ---@param lang string ---@return string local function appendLanguage( lang ) if lang == i18nDefaultLanguage then return '' end ---@type { getRefHtml: ( fun( lang: string ): string ), list_ref: ( fun( frame: frame ): string ) } local langs = require( 'Module:Languages' ) return langs.list_ref( p.currentFrame:newChild{ args = { lang } } ) end ---@param lang string ---@param data source ---@return string local function appendSubtitle( lang, data ) return appendProperty( lang, data, ': ', 'subtitle', nil ) end ---@param lang string ---@param data source ---@return string local function appendOriginalTitle( lang, data ) return appendProperty( lang, data, ' = ', 'originaltitle', nil ) end ---@param lang string ---@param data source ---@return string local function appendPublication( lang, data ) if not data.publication then return '' end local result = ' // ' .. asString( lang, data.publication.title, options_commas_it_short ) if data.publication.subtitle and data.publication.subtitle ~= '' then result = result .. ': ' .. asString( lang, data.publication.subtitle, options_commas_it_short ) end return result end ---@param lang string ---@param data source ---@return string local function appendEditor( lang, data ) if not data.editor and not data.translator then return '' end local result = ' / ' if data.editor then local prefix = i18nEditors[ lang ] or i18nEditors[ i18nDefaultLanguage ] result = result .. prefix .. getPeopleAsWikitext( data.editor, lang, options_commas_responsible ) if data.translator then result = result .. ', ' end end if data.translator then local prefix = i18nTranslators[ lang ] or i18nTranslators[ i18nDefaultLanguage ] result = result .. prefix .. getPeopleAsWikitext( data.translator, lang, options_commas_responsible ) end return result end ---@param lang string ---@param data source local function appendEdition( lang, data ) return appendProperty( lang, data, ' — ', 'edition', nil ) end ---@param lang string ---@param data source ---@return string local function appendPublicationData( lang, data ) if not data.place and not data.publisher and not data.year then return '' end local result = ' — ' if data.place then result = result .. asString( lang, data.place, options_commas_short ) if data.publisher or data.year then result = result .. ': ' end end if data.publisher then result = result .. asString( lang, data.publisher, options_commas_short ) if data.year then result = result .. ', ' end end if data.year then result = result .. asString( lang, data.year, options_commas ) end result = result .. '.' return result end ---@param lang string ---@param data source ---@return string local function appendVolumeAndIssue( lang, data ) if not data.volume and not data.issue then return '' end local result = ' — ' local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ] local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ] if data.volume then result = result .. appendProperty( lang, data, letter_vol .. '&nbsp;', 'volume', nil ) result = result ..appendProperty( lang, data, ', ' .. letter_iss .. '&nbsp;', 'issue', nil ) else result = result .. appendProperty( lang, data, letter_iss .. '&nbsp;', 'issue', nil ) end result = result .. '.' return result end ---@param lang string ---@param data source ---@return string local function appendPages( lang, data ) if not data.pages then return '' end local letter = i18nPages[ lang ] or i18nPages[ i18nDefaultLanguage ] local strPages = asString( lang, data.pages, options_commas ) strPages = mw.ustring.gsub( strPages, '[-—]', '—' ) return ' — ' .. letter .. '&nbsp;' .. strPages .. '.' end ---@param lang string ---@param data source ---@return string local function appendNumberOfPages( lang, data ) if not data.numberOfPages then return '' end local letter = i18nNumberOfPages[ lang ] or i18nNumberOfPages[ i18nDefaultLanguage ] return appendProperty( lang, data, ' — ', 'numberOfPages', nil ) .. '&nbsp;' .. letter end ---@param lang string ---@param data source ---@return string local function appendBookSeries( lang, data ) if not data.bookSeries then return '' end local result = appendProperty( lang, data, ' — (', 'bookSeries', nil ) if data.bookSeriesVolume or data.bookSeriesIssue then result = result .. '; ' local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ] local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ] if data.bookSeriesVolume then result = result .. appendProperty( lang, data, letter_vol .. '&nbsp;', 'bookSeriesVolume', nil ) result = result .. appendProperty( lang, data, ', ' .. letter_iss .. '&nbsp;', 'bookSeriesIssue', nil ) else result = result .. appendProperty( lang, data, letter_iss .. '&nbsp;', 'bookSeriesIssue', nil ) end end result = result .. ')' return result end ---@param lang string ---@param data source ---@return string local function appendTirage( lang, data ) if not data.tirage then return '' end local tirageTemplate = i18nTirage[ lang ] or i18nTirage[ i18nDefaultLanguage ] ---@type options local optionsTirage = { separator = '; ', conjunction = '; ', format = function( _data ) return tostring( mw.ustring.format( tirageTemplate, _data ) ) end, short = false, nolinks = false, preferids = false, } return ' — ' .. asString( lang, data.tirage, optionsTirage ) end ---@param lang string ---@param value string | nil ---@param options options ---@param prefix string? ---@return string local function appendIdentifier( lang, value, options, prefix ) if not value then return '' end return ' — ' .. ( prefix or '' ) .. asString( lang, value, options ) end ---@param result string ---@param lang string ---@param data source ---@return string local function wrapSourceId( result, lang, data ) if not data.sourceId then return result end local citeType = data.type and asString( lang, data.type, options_citetypes ) or 'citetype_unknown' return '<span class="wikidata_cite ' .. citeType .. '" data-entity-id="' .. data.sourceId .. '">' .. result .. '</span>' end ---@param data source ---@return string local function appendAccessDate( data ) if not data.accessdate then return '' end local date = getSingle( data.accessdate ) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local y, m, d = mw.ustring.match( date, pattern ) y, m, d = tonumber( y ), tonumber( m ), tonumber( d ) local date_str = ( d > 0 and ' ' .. tostring( d ) or '' ) .. ( m > 0 and ' ' .. monthGen[ m ] or '' ) .. ( y > 0 and ' ' .. tostring( y ) or '' ) return " <small>Проверено" .. date_str .. ".</small>" end ---@param data source ---@param lang string ---@return void local function populateUrl( data, lang ) if data.sourceId and not data.url then local sitelink = getSitelink( data.sourceId, lang .. 'wikisource' ) if sitelink then data.url = ':' .. lang .. ':s:' .. sitelink end end end ---@param data source ---@return void local function populateYear( data ) if not data.year and data.dateOfPublication then local date = getSingle( data.dateOfPublication ) data.year = mw.ustring.sub( date, 2, 5 ) end if not data.year and data.dateOfCreation then local date = getSingle( data.dateOfCreation ) data.year = mw.ustring.sub( date, 2, 5 ) end end ---@param data source ---@return void local function populateTitle( data ) data.title = data.title or getSingle( data.url ) end ---@param data source ---@return string local function renderSource( data ) local lang = getLangCode( data.lang ) or i18nDefaultLanguage preprocessPlace( data, lang ) populateUrl( data, lang ) populateTitle( data ) if not data.title then return '' end populateYear( data ) local result = generateAuthorLinks( lang, data ) result = result .. appendTitle( lang, data ) result = result .. appendLanguage( lang ) result = result .. appendSubtitle( lang, data ) result = result .. appendOriginalTitle( lang, data ) result = result .. appendPublication( lang, data ) result = result .. '<span class="wef_low_priority_links">' result = result .. appendEditor( lang, data ) -- Might take current editor instead of actual. Use with caution result = result .. appendEdition( lang, data ) result = result .. appendPublicationData( lang, data ) result = result .. appendVolumeAndIssue( lang, data ) result = result .. appendPages( lang, data ) result = result .. appendNumberOfPages( lang, data ) result = result .. appendBookSeries( lang, data ) result = result .. appendTirage( lang, data ) result = result .. appendIdentifier( lang, data.isbn, options_commas, 'ISBN ' ) result = result .. appendIdentifier( lang, data.issn, options_issn, 'ISSN ' ) result = result .. appendIdentifier( lang, data.doi, options_doi, nil ) result = result .. appendIdentifier( lang, data.pmid, options_pmid, nil ) result = result .. appendIdentifier( lang, data.arxiv, options_arxiv, nil ) result = result .. appendAccessDate( data ) result = result .. '</span>' return wrapSourceId( result, lang, data ) end ---@param data source Данные в простом формате, согласованном с модулями формирования библиографического описания ---@param snaks snaks ---@return string | nil local function renderReferenceImpl( data, snaks ) -- не показывать источники с "импортировано из" if snaks.P143 then return nil end -- забрать данные из reference populateDataFromSnaks( snaks or {}, data, PROPERTY_MAP ) data.sourceId = getSingle( data.sourceId ) populateDataFromEntity( data.sourceId, data, PROPERTY_MAP ) expandSpecials( data ) populateSourceDataImpl( data.sourceId, data, PROPERTY_MAP ) expandPublication( data ) expandBookSeries( data ) if next( data ) == nil then return nil end local rendered = renderSource( data ) if mw.ustring.len( rendered ) == 0 then return nil end if data.ref then local anchorValue = 'CITEREF' .. data.ref .. ( coalesce( { data[ 'ref-year' ], data.year } ) or '' ) rendered = '<span class="citation" id="' .. mw.uri.anchorEncode( anchorValue ) .. '">' .. rendered .. '</span>' end return rendered end ---@param frame frame ---@param currentEntityId string | { id: string } ---@param reference table{ snaks: snaks } ---@return string | nil function p.renderSource( frame, currentEntityId, reference ) reference = reference or { snaks = {} } p.currentFrame = frame local data = getFilledArgs( frame.args or {} ) populateDataFromSnaks( reference.snaks, data, PROPERTY_MAP ) data.sourceId = getSingle( data.sourceId ) if not currentEntityId then data.entityId = mw.wikibase.getEntityIdForCurrentPage() elseif type( currentEntityId ) == 'string' then data.entityId = currentEntityId elseif type( currentEntityId ) == 'table' and currentEntityId.id then data.entityId = currentEntityId.id end ---@type string local rendered = renderReferenceImpl( data, reference.snaks or {} ) if not rendered then return '' end return rendered end ---@param frame frame ---@param currentEntityId string ---@param reference table ---@return string function p.renderReference( frame, currentEntityId, reference ) local rendered = p.renderSource( frame, currentEntityId, reference ) if not rendered or rendered == '' then return '' end -- Про выбор алгоритма хеширования см. [[Модуль:Hash]]. Знак подчёркивания в начале позволяет -- исключить ошибку, когда имя сноски — чисто числовое значение, каковыми иногда бывают хеши. return frame:extensionTag( 'ref', rendered, { name = '_' .. mw.hash.hashValue( 'fnv164', rendered ) } ) .. '[[Category:Википедия:Статьи с источниками из Викиданных]]' end ---@param frame frame ---@return string | nil function p.testPersonNameToAuthorName( frame ) return personNameToAuthorName( frame.args[ 1 ] ) end ---@param frame frame ---@return string | nil function p.testPersonNameToResponsibleName( frame ) return personNameToResponsibleName( frame.args[ 1 ] ) end return p 752a204827a41ecd6cf518bdb22da12718bca2ec Модуль:Message box/ombox.css 828 73 156 2024-06-21T16:47:35Z wikipedia, ruwikipedia>Putnik 0 исправление цвета рамки text text/plain /* Скопировано из [[:en:Module:Message box/ombox.css]] */ .ombox { margin: 4px 0; border-collapse: collapse; border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */ background-color: var(--background-color-neutral-subtle, #f8f9fa); box-sizing: border-box; } /* For the "small=yes" option. */ .ombox.mbox-small { font-size: 88%; line-height: 1.25em; } .ombox-speedy { border: 2px solid var(--border-color-error, #b32424); /* Red */ background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */ } .ombox-delete { border: 2px solid var(--background-color-error--active, #b32424); /* Red */ } .ombox-content { border: 1px solid #f28500; /* Orange */ } .ombox-style { border: 1px solid #fc3; /* Yellow */ } .ombox-move { border: 1px solid #9932cc; /* Purple */ } .ombox-protection { border: 2px solid var(--border-color-base, #a2a9b1); /* Gray-gold */ } .ombox .mbox-text { border: none; /* @noflip */ padding: 0.25em 0.9em; width: 100%; } .ombox .mbox-image { border: none; /* @noflip */ padding: 2px 0 2px 0.9em; text-align: center; } .ombox .mbox-imageright { border: none; /* @noflip */ padding: 2px 0.9em 2px 0; text-align: center; } /* An empty narrow cell */ .ombox .mbox-empty-cell { border: none; padding: 0; width: 1px; } .ombox .mbox-invalid-type { text-align: center; } /* Хак, TODO: посмотреть, как оно на самом деле работает */ .ombox .mbox-textsmall-div { font-size: 90%; } @media (min-width: 720px) { .ombox { margin: 4px 10%; } .ombox.mbox-small { /* @noflip */ clear: right; /* @noflip */ float: right; /* @noflip */ margin: 4px 0 4px 1em; width: 238px; } /* Стили нотификаций для ноутбуков */ @media (max-width: 1366px) { .ombox { margin-left: 6%; margin-right: 6%; } } } /* [[Категория:Модули:Подстраницы CSS]] */ 6627874170f6674674bfa5796b2f7dfb6698cd81 Шаблон:Doc/begin 10 54 118 2024-06-30T22:14:58Z wikipedia, ruwikipedia>Putnik 0 [[ВП:×|отмена]] правки 138443392 участника [[Special:Contribs/Putnik|Putnik]] ([[UT:Putnik|обс.]]) wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Doc/styles.css" /> <div class="ts-doc-doc" id="doc"> <div class="ts-doc-header" id="Документация"> <div class="ts-doc-heading">Документация</div> {{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }} </div> <div class="ts-doc-content"></includeonly><noinclude> {{doc}} </noinclude> c753f0a9f65d86707cdffaf93fb49c2c52daf92b Модуль:Navbar 828 63 136 2024-07-08T20:00:10Z wikipedia, ruwikipedia>Putnik 0 более контрастная серая иконка шестерёнки в тёмной теме Scribunto text/plain local p = {} local hlist = 'Template:Flatlist/styles.css' local templatestyles = 'Module:Navbar/styles.css' local getArgs function p._ruwikiNavbar( args ) local titleText = args[ 1 ] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local title = mw.title.new(mw.text.trim(titleText), 'Template'); if not title then error('Invalid title ' .. titleText) end local whiteColorDefs = { ['#fff'] = true, ['#ffffff'] = true, ['white'] = true, } local fontColor = args.fontcolor and args.fontcolor:lower() local isWhite = fontColor and whiteColorDefs[ fontColor ] == true local fontStyle = args.fontstyle and mw.text.unstripNoWiki( args.fontstyle:lower() ) if not isWhite and fontStyle then local styleratio = require( 'Module:Color contrast' )._styleratio isWhite = styleratio( { fontStyle .. '; color:#666;', '', '#666' } ) < 3.66 end local isTemplate = title.namespace == 10 local altText = string.format( 'Перейти %s «%s»', isTemplate and 'к шаблону' or 'на страницу', mw.text.split( isTemplate and title.text or title.fullText, '#' )[ 1 ] ) return string.format( '[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|class=noprint%s|link=%s|%s]]', isWhite and ' white' or '', isWhite and '' or ' skin-invert-image', tostring( title ), altText ) end function p.ruwikiNavbar(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._ruwikiNavbar(getArgs(frame)) end function p._navbar(args) local titleArg = 1 if args.collapsible then titleArg = 2 if not args.plain then args.mini = 1 end if args.fontcolor then args.fontstyle = 'color:' .. args.fontcolor .. ';' end args.style = 'float:left; text-align:left; white-space:nowrap;' end if args[titleArg] == 'off' then return end local titleText = args[titleArg] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local title = mw.title.new(mw.text.trim(titleText), 'Template'); if not title then error('Invalid title ' .. titleText) end local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or ''; local tag if args.nodiv then tag = 'span' else tag = 'div' end local div = mw.html.create():tag(tag) div :addClass('navbar hlist plainlinks noprint') :attr('data-navboxnavigation-link', '0') :cssText(args.style) if args.mini then div:addClass('navbar-mini') end if not (args.mini or args.plain) then div :tag('span') :addClass('navbar-boxtext') :cssText(args.fontstyle) :wikitext(args.text or 'Шаблон:') :wikitext(' ') end local ul = div:tag('ul'); if args.brackets then ul:addClass('navbar-brackets') end ul :tag('li') :addClass('nv-view') :wikitext('[[' .. title.fullText .. '|') :tag(args.mini and 'abbr' or 'span') :addClass(args.mini and 'navbar-mini-abbr') :attr('title', 'Просмотр этого шаблона') :cssText(args.fontstyle) :wikitext(args.mini and 'п' or 'просмотр') :done() :wikitext(']]') :done() :tag('li') :addClass('nv-talk') :wikitext('[[' .. talkpage .. '|') :tag(args.mini and 'abbr' or 'span') :attr('title', 'Обсуждение этого шаблона') :cssText(args.fontstyle) :wikitext(args.mini and 'о' or 'обсуждение') :done() :wikitext(']]'); if not args.noedit then ul :tag('li') :addClass('nv-edit') :wikitext('[[Special:EditPage/' .. title.fullText .. '|') :tag(args.mini and 'abbr' or 'span') :attr('title', 'Править этот шаблон') :cssText(args.fontstyle) :wikitext(args.mini and 'р' or 'править') :done() :wikitext(']]'); end if args.collapsible then div:done() :tag('span') :addClass( args.mini and 'navbar-ct-mini' or 'navbar-ct-full' ) :cssText(args.fontstyle) :wikitext(args[1]) end local frame = mw.getCurrentFrame() return frame:extensionTag{ name = 'templatestyles', args = { src = hlist } } .. frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles } } .. tostring(div:done()) end function p.navbar(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._navbar(getArgs(frame)) end return p 695777e4dafbd5f7bf8b4f35d8db9349d08a363d Шаблон:Doc/styles.css 10 55 120 2024-08-05T07:09:06Z wikipedia, ruwikipedia>Putnik 0 исправление кода для тёмной темы ([[phab:T369874]]) text text/plain .ts-doc-doc { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); clear: both; margin-top: 1em; } /* Ctrl+F ":target" in [[MediaWiki:Common.css]] */ .ts-doc-doc sup.reference:target, .ts-doc-doc ol.references li:target, .ts-doc-doc .highlight-target:target, .ts-doc-doc cite:target, .ts-doc-doc span.citation:target { background: var(--ruwiki-background-color-blue200, #cfe3ff); } .ts-doc-header { align-items: center; background: var(--ruwiki-background-color-blue200, #cfe3ff); display: flex; flex-wrap: wrap; padding: .642857em 1em .5em; overflow: hidden; } .ts-doc-header .ts-tlinks-tlinks { margin-left: auto; } .ts-doc-content { padding: .214286em 1em; } .ts-doc-content:after { content: ''; clear: both; display: block; } .ts-doc-heading { display: inline-block; padding-left: 2em; background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat; background-size: contain; font-size: small; min-height: 1.75em; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; } @media screen { html.skin-theme-clientpref-night .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } .ts-doc-content > *:first-child, .ts-doc-footer > *:first-child { margin-top: .5em; } .ts-doc-content > *:last-child, .ts-doc-footer > *:last-child { margin-bottom: .5em; } .ts-doc-footer { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); padding: .214286em 1em; margin-top: .214286em; margin-bottom: .214286em; font-style: italic; } @media (max-width: 719px) { .ts-doc-header { display: block; } .ts-doc-header .ts-tlinks-tlinks { float: none; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ be8d912472a37a6051bee114da86f913839e7ca0 Модуль:Message box/configuration 828 18 46 2024-08-29T15:57:44Z wikipedia, ruwikipedia>Putnik 0 замена notheme на стили тёмной темы для cmbox Scribunto text/plain -------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = { class = 'ambox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'ambox-delete', image = 'Stop hand nuvola.svg' }, content = { class = 'ambox-content', image = 'Emblem-important.svg' }, style = { class = 'ambox-style', image = 'Broom_icon.svg' }, move = { class = 'ambox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'ambox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'ambox-notice', image = 'Information.svg' }, good = { class = 'ambox-good', image = 'Green star boxed.svg' }, serious = { class = 'ambox-serious', image = 'Stop hand nuvola.svg' }, merge = { class = 'ambox-merge', image = 'Merge-split-transwiki default.svg' }, discussion = { class = 'ambox-discussion', image = 'Nuvola apps ksirc.png' } }, default = 'notice', allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'}, allowSmall = true, smallParam = 'left', smallClass = 'mbox-small-left', substCheck = true, classes = {'metadata', 'ambox'}, imageEmptyCell = true, imageCheckBlank = true, imageSmallSize = '20x20px', imageCellDiv = true, useCollapsibleTextFields = true, imageRightNone = true, sectionDefault = 'статья', allowMainspaceCategories = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для статей', templateCategoryRequireName = true, templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами', templateErrorParamsToCheck = {'issue', 'fix'}, removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]', templatestyles = 'Module:Message box/ambox.css', }, cmbox = { types = { speedy = { class = 'cmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'cmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'cmbox-content', image = 'Ambox important.svg' }, style = { class = 'cmbox-style', image = 'Edit-clear.svg' }, move = { class = 'cmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'cmbox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'cmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'cmbox'}, imageEmptyCell = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/cmbox.css', }, fmbox = { types = { warning = { class = 'fmbox-warning', image = 'Ambox warning pn.svg' }, editnotice = { class = 'fmbox-editnotice', image = 'Information icon4.svg' }, system = { class = 'fmbox-system', image = 'Information icon4.svg' } }, default = 'system', showInvalidTypeError = true, classes = {'fmbox'}, imageEmptyCell = false, imageRightNone = false, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/fmbox.css', }, imbox = { types = { speedy = { class = 'imbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'imbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'imbox-content', image = 'Ambox important.svg' }, style = { class = 'imbox-style', image = 'Edit-clear.svg' }, move = { class = 'imbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'imbox-protection', image = 'Padlock-silver-medium.svg' }, license = { class = 'imbox-license licensetpl', image = 'Imbox license.png' -- @todo We need an SVG version of this }, featured = { class = 'imbox-featured', image = 'Cscr-featured.svg' }, notice = { class = 'imbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'imbox'}, imageEmptyCell = true, below = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов', templatestyles = 'Module:Message box/imbox.css', }, ombox = { types = { speedy = { class = 'ombox-speedy', image = 'OOjs UI icon alert-destructive.svg' }, delete = { class = 'ombox-delete', image = 'OOjs UI icon alert-destructive.svg' }, content = { class = 'ombox-content', image = 'OOjs UI icon notice-warning.svg' }, style = { class = 'ombox-style', image = 'Edit-clear.svg' }, move = { class = 'ombox-move', image = 'Imbox move.png' }, protection = { class = 'ombox-protection', image = 'Imbox protection.png' }, notice = { class = 'ombox-notice', image = 'OOjs UI icon info-progressive.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'ombox'}, allowSmall = true, imageEmptyCell = true, imageRightNone = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/ombox.css', }, tmbox = { types = { speedy = { class = 'tmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'tmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'tmbox-content', image = 'Ambox important.svg' }, style = { class = 'tmbox-style', image = 'Edit-clear.svg' }, move = { class = 'tmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'tmbox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'tmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'tmbox'}, allowSmall = true, imageRightNone = true, imageEmptyCell = true, imageEmptyCellStyle = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений', templatestyles = 'Module:Message box/tmbox.css', } } 2c0750ec1561e8ec25c0988c411f3c69e4957483 Шаблон:Государство/doc 10 104 218 2024-09-11T09:57:25Z wikipedia, ruwikipedia>A1788 0 wikitext text/x-wiki {{docpage}} Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи о современных государствах; * для исторических государств используйте {{t|историческое государство}}. * для составных частей государств используйте {{t|Административная единица}}. == Образец для копирования == <pre> {{Государство |Статус = <!-- виртуальное / непризнанное / частично признанное / регион; для признанных государств не заполнять --> |Русское название = |Оригинальное название = |Родительный падеж = |Герб = |Вместо герба = |Девиз = {{lang-??2|}}<!-- на оф. языке / языках гос-ва --> |Перевод девиза = |Название гимна = |Перевод названия гимна = |Аудио = |Форма правления = |Государственный строй = |Государственная религия = |На карте = |подпись к карте = |На карте2 = |Язык/Языки = |Основано/Основана = |Дата/Даты независимости = |Независимость от = |Столица = |Крупнейшие города = |Должность руководителя 1 = |Руководитель 1 = |Должность руководителя 2 = |Руководитель 2 = |Должность руководителя 3 = |Руководитель 3 = |Должность руководителя 4 = |Руководитель 4 = |Должность руководителя 5 = |Руководитель 5 = |Место по территории = |Территория = |Процент воды = |Этнохороним = |Место по населению = |Население = |Год оценки = |Население по переписи = |Год переписи = |Плотность населения = |Место по плотности = |ВВП (ППС) = |Год расчёта ВВП (ППС) = |Место по ВВП (ППС) = |ВВП (ППС) на душу населения = |Место по ВВП (ППС) на душу населения = |ВВП (номинал) = |Год расчёта ВВП (номинал) = |Место по ВВП (номинал) = |ВВП (номинал) на душу населения = |Место по ВВП (номинал) на душу населения = |ИРЧП = |Год расчёта ИРЧП = |Место по ИРЧП = |Уровень ИРЧП = |Валюта = |Домен/Домены = |Телефонный код = |Часовой пояс = |Автомобильное движение = |Примечания = <!-- |Без флага и герба=* --> <!-- |Без гимна=* --> }} </pre> == Описание параметров == Некоторые параметры могут быть заданы в разных формах (например, в единственном либо множественном числе). После копирования образца в статью заполните только строку с более подходящей формой. Например, в статье [[Албания]]&nbsp;— <pre> |Язык = [[Албанский язык|албанский]]</pre> а в статье [[Канада]]&nbsp;— <pre> |Языки = [[Английский язык|английский]] и [[Французский язык|французский]]</pre> Для статей о регионах с нечётким правовым статусом используйте параметр <code>Спорный статус = да</code> и параметры «Основано», «Дата образования», «Провозглашение независимости» и «Дипломатическое признание» вместо «Дата независимости» и «Основано»: <pre> |Спорный статус = да |Основано = |Основана = |Дата образования = |Провозглашение независимости = |Дипломатическое признание = |Независимость от = </pre> Для статей о [[Непризнанные и частично признанные государства|непризнанных государствах]] или [[Автономный регион|автономных регионах]], не являющихся самостоятельными государствами, используйте параметр <code>Статус&nbsp;=&nbsp;непризнанное</code> или <code>Статус = регион</code>, это отключит автоматическое добавление категории [[:Категория:Государства по алфавиту|Государства по алфавиту]], а в первом случае также добавит категорию [[:Категория:Непризнанные государства|Непризнанные государства]]. Для статей о [[Виртуальное государство|виртуальных государствах]] используйте параметр <code>Статус = виртуальное</code>, это добавит категорию [[:Категория:Виртуальные государства|Виртуальные государства]]. == Пример использования == {{demo|reverse=1|br=|<nowiki>{{Государство |Русское название = Финляндская Республика |Оригинальное название = {{lang-fi|Suomen Tasavalta}}<br>{{lang-sv|Republiken Finland}} |Родительный падеж = Финляндии |Герб = Coat of arms of Finland.svg |Флаг = Flag of Finland.svg<!-- иначе используется конструкция {{флаг|{{FULLPAGENAME}}|размер=135px}} --> |Вместо герба = |Девиз = |Перевод девиза = |Название гимна = Maamme |Перевод названия гимна = Наш край |Аудио = |Форма правления = [[президентская республика]] |Государственный строй = [[унитарное государство]] |Государственная религия = |На карте = EU-Finland.svg |подпись к карте = Расположение '''Финляндии''' (тёмно-зелёный):<br>— в [[Европа|Европе]] (светло-зелёный и тёмно-серый)<br>— в [[Европейский союз|Европейском союзе]] (светло-зелёный) |На карте2 = |Языки = [[финский язык|финский]], [[шведский язык|шведский]] |Основано/Основана = |Дата независимости = [[6 декабря]] [[1917]] |Независимость от = [[Россия|России]] |Столица = [[Хельсинки]] |Крупнейший город = Хельсинки |Должность руководителя 1 = [[Президент Финляндии|Президент]] |Руководитель 1 = [[Халонен, Тарья Каарина|Тарья Халонен]] |Должность руководителя 2 = [[Премьер-министр Финляндии|Премьер-министр]] |Руководитель 2 = [[Ванханен, Матти Танели|Матти Ванханен]] |Место по территории = 63 |Территория = 338 145 |Процент воды = 9,96 |Этнохороним = финляндец, финляндка |Место по населению = 106 |Население = 5 219 732 |Год оценки = 2003 |Население по переписи = |Год переписи = |Плотность населения = 15,4 |Место по плотности = |ВВП = |Год расчёта ВВП = |Место по ВВП = |ВВП на душу населения = |Место по ВВП на душу населения = |ИРЧП = |Год расчёта ИРЧП = |Место по ИРЧП = |Уровень ИРЧП = |Валюта = [[евро]]<ref name="money">до 2002 — [[финская марка]]</ref> |Домены = [[.fi]], [[.ax]] (для [[Аландские острова|Аландских островов]]) |Телефонный код = 358 |Часовой пояс = +2 |Автомобильное движение = |Примечания = <references/> }}</nowiki>}} == TemplateData == <templatedata> { "params": { "Спорный статус": {}, "Статус": {}, "Русское название": {}, "Оригинальное название": {}, "Флаг": { "type": "wiki-file-name" }, "Ссылка на флаг": {}, "Родительный падеж": {}, "Герб": { "type": "wiki-file-name" }, "Отображаемая подпись герба": {}, "Вместо герба": {}, "Девиз": {}, "Перевод девиза": {}, "Без гимна": {}, "Название гимна": {}, "Перевод названия гимна": {}, "Аудио": {}, "На карте": {}, "На карте2": {}, "Дата1": {}, "Дата2": {}, "Дата3": {}, "Дата4": {}, "Дата5": {}, "Дата6": {}, "Дата7": {}, "Дата8": {}, "Дата9": {}, "Дата10": {}, "Дата11": {}, "Дата12": {}, "sovereignty_type": {}, "Этап1": {}, "Этап2": {}, "Этап3": {}, "Этап4": {}, "Этап5": {}, "Этап6": {}, "Этап7": {}, "Этап8": {}, "Этап9": {}, "Этап10": {}, "Этап11": {}, "Этап12": {}, "Основана": {}, "Основано": {}, "Дата образования": {}, "Провозглашение независимости": {}, "Независимость от": {}, "Дипломатическое признание": {}, "Отображаемый тип независимости": {}, "Даты независимости": {}, "Дата независимости": {}, "Язык": {}, "Языки": {}, "Столица": {}, "Крупнейший город": {}, "Крупнейшие города": {}, "Форма правления": {}, "Должность руководителя 1": {}, "Должности руководителей": {}, "Руководитель 1": {}, "Руководители": {}, "Должность руководителя 2": {}, "Руководитель 2": {}, "Должность руководителя 3": {}, "Руководитель 3": {}, "Должность руководителя 4": {}, "Руководитель 4": {}, "Должность руководителя 5": {}, "Руководитель 5": {}, "Государственная религия": {}, "Место по территории": {}, "Территория": {}, "Процент воды": {}, "Территория2": {}, "Население": {}, "Год оценки": {}, "Год переписи": {}, "Население2": {}, "Место по населению": {}, "Население по переписи": {}, "Плотность населения": {}, "Место по плотности": {}, "ВВП": {}, "Год расчёта ВВП": {}, "Место по ВВП": {}, "ВВП на душу населения": {}, "Место по ВВП на душу населения": {}, "ВВП (ППС)": {}, "Год расчёта ВВП (ППС)": {}, "Место по ВВП (ППС)": {}, "ВВП (ППС) на душу населения": {}, "Место по ВВП (ППС) на душу населения": {}, "ВВП (номинал)": {}, "Год расчёта ВВП (номинал)": {}, "Место по ВВП (номинал)": {}, "ВВП (номинал) на душу населения": {}, "Место по ВВП (номинал) на душу населения": {}, "Год расчёта ИРЧП": {}, "ИРЧП": {}, "Уровень ИРЧП": {}, "Место по ИРЧП": {}, "Этнохороним": {}, "Валюта": {}, "Домены": {}, "Домен": {}, "Телефонный код": {}, "Часовые пояса": {}, "Часовой пояс": {}, "Примечания": {}, "nocat": { "type": "boolean" }, "lat_deg": {}, "lat_min": {}, "lat_sec": {}, "lat_dir": {}, "lon_deg": {}, "lon_min": {}, "lon_sec": {}, "lon_dir": {}, "region": {}, "CoordScale": {}, "Размер герба": { "aliases": [ "размер герба" ], "type": "number" }, "Размер флага": { "aliases": [ "размер флага" ], "type": "number" }, "Размер карты": { "aliases": [ "размер карты" ] }, "Подпись к карте": { "aliases": [ "подпись к карте" ] }, "Размер карты2": { "aliases": [ "размер карты2" ] }, "Государственный строй": {}, "Автомобильное движение": {} }, "paramOrder": [ "Статус", "Спорный статус", "Русское название", "Оригинальное название", "Флаг", "Размер флага", "Ссылка на флаг", "Родительный падеж", "Герб", "Размер герба", "Отображаемая подпись герба", "Вместо герба", "Девиз", "Перевод девиза", "Без гимна", "Название гимна", "Перевод названия гимна", "Аудио", "На карте", "Размер карты", "Подпись к карте", "На карте2", "Размер карты2", "Дата1", "Дата2", "Дата3", "Дата4", "Дата5", "Дата6", "Дата7", "Дата8", "Дата9", "Дата10", "Дата11", "Дата12", "sovereignty_type", "Этап1", "Этап2", "Этап3", "Этап4", "Этап5", "Этап6", "Этап7", "Этап8", "Этап9", "Этап10", "Этап11", "Этап12", "Основана", "Основано", "Дата образования", "Провозглашение независимости", "Независимость от", "Дипломатическое признание", "Отображаемый тип независимости", "Даты независимости", "Дата независимости", "Язык", "Языки", "Столица", "Крупнейший город", "Крупнейшие города", "Форма правления", "Государственный строй", "Должность руководителя 1", "Должности руководителей", "Руководитель 1", "Руководители", "Должность руководителя 2", "Руководитель 2", "Должность руководителя 3", "Руководитель 3", "Должность руководителя 4", "Руководитель 4", "Должность руководителя 5", "Руководитель 5", "Государственная религия", "Место по территории", "Территория", "Процент воды", "Территория2", "Население", "Год оценки", "Год переписи", "Население2", "Место по населению", "Население по переписи", "Плотность населения", "Место по плотности", "ВВП", "Год расчёта ВВП", "Место по ВВП", "ВВП на душу населения", "Место по ВВП на душу населения", "ВВП (ППС)", "Год расчёта ВВП (ППС)", "Место по ВВП (ППС)", "ВВП (ППС) на душу населения", "Место по ВВП (ППС) на душу населения", "ВВП (номинал)", "Год расчёта ВВП (номинал)", "Место по ВВП (номинал)", "ВВП (номинал) на душу населения", "Место по ВВП (номинал) на душу населения", "Год расчёта ИРЧП", "ИРЧП", "Уровень ИРЧП", "Место по ИРЧП", "Этнохороним", "Валюта", "Домены", "Домен", "Телефонный код", "Часовые пояса", "Часовой пояс", "Автомобильное движение", "Примечания", "lat_deg", "lat_min", "lat_sec", "lat_dir", "lon_deg", "lon_min", "lon_sec", "lon_dir", "region", "CoordScale", "nocat" ], "format": "block" } </templatedata> == См. также == * {{tl|Историческое государство}} <includeonly> [[Категория:Шаблоны-карточки:Географические объекты]] </includeonly> b1e2b1107db0671d3bcc4dda5bd29020192c442e Шаблон:Docpage 10 60 130 2024-09-25T09:40:06Z wikipedia, ruwikipedia>Stjn 0 __EXPECTED_UNCONNECTED_PAGE__ wikitext text/x-wiki <includeonly>{{#ifeq: {{SUBPAGENAME}} | doc | {{fmbox | class = hlist nowraplinks | style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff); | image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]] | text = <div> * [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]] * [[:{{SUBJECTPAGENAME}}|Документация]] * [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]] * [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} | ** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}} }}</div><!-- -->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }} }}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}} | Модуль | [[Категория:Модули:Документация]] | [[Категория:Шаблоны:Документация]] }}__EXPECTED_UNCONNECTED_PAGE__ }} }}</includeonly><noinclude>{{doc}}</noinclude> e2d07566c50be35ac409e8396893a3b9d8676e0c Шаблон:Карточка/styles.css 10 105 220 2024-10-01T01:43:01Z wikipedia, ruwikipedia>Stjn 0 перенос стилей из [[шаблон:Карточка/флаг и герб]] text text/plain /* Вынесено из [[MediaWiki:Common.css]] и [[MediaWiki:Mobile.css]] */ /* [[Шаблон:Карточка/флаг и герб]] */ .ts-infobox-flaginfo { background: none; border-collapse: collapse; display: table; text-align: center; width: 100%; } .ts-infobox-flaginfo td { vertical-align: middle; } body.skin--responsive.skin-minerva.skin-minerva .ts-infobox-flaginfo td { /* Минерва требует хаков, чтобы эти стили работали */ border-bottom: 0; vertical-align: middle; } /* Таблицы */ .infobox-table, .infobox-tablebox { padding: 0; } .infobox-inner-table, .infobox-table > table, .infobox-tablebox > table { width: 100%; display: table; margin: 0; background: transparent; } .infobox-tablebox > table { border: 1px solid var(--border-color-base, #a2a9b1); border-collapse: separate; } /* Встраиваемая карточка */ .infobox-child { width: 100%; margin: 0; padding: 0; border: none; font-size: 100%; } body.skin-minerva table.infobox-child { width: 100% !important; margin: 0 !important; padding: 0; border: none; font-size: 100%; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 25901ad6113ef3908fc70305ce64eb64925c665f Шаблон:Карточка/флаг и герб 10 98 206 2024-10-24T14:21:28Z wikipedia, ruwikipedia>Putnik 0 fix wikitext text/x-wiki {{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<templatestyles src="Шаблон:Карточка/styles.css" /><table role="presentation" class="ts-infobox-flaginfo"> <tr> {{if-wikidata|p41|{{{флаг|}}}|<td>{{wikidata|p41|{{{флаг|}}}|from={{{from|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}} {{if-wikidata|p94|{{{герб|}}}|<td>{{wikidata|p94|{{{герб|}}}|from={{{from|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}} </tr> {{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<tr> {{if-wikidata|p41|{{{флаг|}}}|3=<td class="media-caption">{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}} {{if-wikidata|p94|{{{герб|}}}|3=<td class="media-caption">{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}} </tr>}}</table> }}<noinclude> {{doc}} </noinclude> 1790949866597b0909572cd51fdfb8b9a7db55ff Модуль:Wikidata 828 82 174 2024-10-26T15:17:47Z wikipedia, ruwikipedia>Stjn 0 [[ВП:×|отмена]]: сломало отображение в множестве статей Scribunto text/plain ---settings, may differ from project to project local fileDefaultSize = '267x400px' local outputReferences = true local writingSystemElementId = 'Q8209' local langElementId = 'Q7737' ---Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании) local moduleSources = require( 'Module:Sources' ) local WDS = require( 'Module:WikidataSelectors' ) ---Константы ---@type string local CONTENT_LANGUAGE_CODE = mw.language.getContentLanguage():getCode() local p = {} local g_config, g_frame local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement, formatStatementDefault, getSourcingCircumstances, getPropertyParams ---@param obj table ---@param target table ---@param skipEmpty boolean | nil ---@return table local function copyTo( obj, target, skipEmpty ) for key, val in pairs( obj ) do if skipEmpty ~= true or ( val ~= nil and val ~= '' ) then target[ key ] = val end end return target end ---@param prev number | nil ---@param next number | nil ---@return number | nil local function min( prev, next ) if prev == nil or prev > next then return next end return prev end ---@param prev number | nil ---@param next number | nil ---@return number | nil local function max( prev, next ) if prev == nil or prev < next then return next end return prev end ---@param section string ---@param code string ---@return any | nil local function getConfig( section, code ) if g_config == nil then g_config = require( 'Module:Wikidata/config' ) end if not g_config then g_config = {} end if not section then return g_config end if not code then return g_config[ section ] or {} end if not g_config[ section ] then return nil end return g_config[ section ][ code ] end ---@param code string ---@param sortKey string | nil ---@return string local function getCategoryByCode( code, sortKey ) local value = getConfig( 'categories', code ) if not value or value == '' then return '' end if sortKey ~= nil then return '[[Category:' .. value .. '|' .. sortKey .. ']]'; -- экранировать? else return '[[Category:' .. value .. ']]' end end ---@param isoStr string | table ---@return table | nil local function splitISO8601( isoStr ) if 'table' == type( isoStr ) then if isoStr.args and isoStr.args[ 1 ] then isoStr = '' .. isoStr.args[ 1 ] else return 'unknown argument type: ' .. type( isoStr ) .. ': ' .. table.tostring( isoStr ) end end local Y, M, D = ( function( str ) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local _Y, _M, _D = mw.ustring.match( str, pattern ) return tonumber( _Y ), tonumber( _M ), tonumber( _D ) end )( isoStr ) local h, m, s = ( function( str ) local pattern = "T(%d+):(%d+):(%d+)%Z" local _H, _M, _S = mw.ustring.match( str, pattern ) return tonumber( _H ), tonumber( _M ), tonumber( _S ) end )( isoStr ) local oh, om = ( function( str ) if str:sub(-1) == "Z" then -- ends with Z, Zulu time return 0, 0 end -- matches ±hh:mm, ±hhmm or ±hh; else returns nils local pattern = "([-+])(%d%d):?(%d?%d?)$" local sign, oh, om = mw.ustring.match( str, pattern ) sign, oh, om = sign or "+", oh or "00", om or "00" return tonumber( sign .. oh ), tonumber( sign .. om ) end )( isoStr ) return { year=Y, month=M, day=D, hour=( h + oh ), min=( m + om ), sec=s } end ---Внутренняя функции для получения границ временного диапазона ---@param time string ---@param precision number ---@return table | nil function p._parseTimeBoundaries( time, precision ) local s = splitISO8601( time ) if not s then return nil end if precision >= 0 and precision <= 8 then local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 } local power = powers[ precision + 1 ] local left = s.year - ( s.year % power ) return { tonumber( os.time( { year=left, month=1, day=1, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 9 then return { tonumber( os.time( { year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000, tonumber( os.time( { year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 } end if precision == 10 then local lastDays = { 31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } local lastDay = lastDays[ s.month ] return { tonumber( os.time( { year=s.year, month=s.month, day=1, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 11 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 12 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 13 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58 } ) ) * 1000 + 1999 } end if precision == 14 then local t = tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) return { t * 1000, t * 1000 + 999 } end error( 'Unsupported precision: ' .. precision ) end ---Внутренняя функция для получения числового значения времени из snak'а ---@param table snak ---@return number | nil function p._parseTimeFromSnak( snak ) if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time then local timeData = splitISO8601( tostring( snak.datavalue.value.time ) ) timeData.month = math.max( timeData.month, 1 ) timeData.day = math.max( timeData.day, 1 ) return tonumber( os.time( timeData ) ) * 1000 end return nil end ---Функция для формирования категории на основе wikidata/config ---@param options table ---@param entityId string ---@return string local function extractCategory( options, entityId ) if not entityId or not options.category or options.nocat then return '' end if type( entityId ) ~= 'string' then entityId = entityId.id end local claims = WDS.load( entityId, options.category ) if not claims then return '' end for _, claim in pairs( claims ) do if claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.type == 'wikibase-entityid' then local catEntityId = claim.mainsnak.datavalue.value.id local wbStatus, catSiteLink = pcall( mw.wikibase.getSitelink, catEntityId ) if wbStatus and catSiteLink then return '[[' .. catSiteLink .. ']]' end end end return '' end ---Преобразует строку в булевое значение ---@param valueToParse string ---@return boolean Преобразованное значение, если его удалось распознать, или defaultValue во всех остальных случаях local function toBoolean( valueToParse, defaultValue ) if valueToParse ~= nil then if valueToParse == false or valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then return false end return true end return defaultValue end ---Обрачивает отформатированное значение в инлайновый или блочный тег. ---@param value string value ---@param attributes table of attributes ---@return string HTML tag with value local function wrapValue( value, attributes ) local tagName = 'span' local spacer = '' if string.match( value, '\n' ) or string.match( value, '<t[dhr][ >]' ) or string.match( value, '<div[ >]' ) or string.find( value, 'UNIQ%-%-imagemap' ) then tagName = 'div' spacer = '\n' end local attrString = '' for key, val in pairs( attributes or {} ) do local _key = mw.text.trim( key ) local _value = mw.text.encode( mw.text.trim( val ) ) attrString = attrString .. _key .. '="' .. _value .. '" ' end return '<' .. tagName .. ' ' .. attrString .. '>' .. spacer .. value .. '</' .. tagName .. '>' end ---Wraps formatted snak value into HTML tag with attributes. ---@param value string value of snak ---@param hash string ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapSnak( value, hash, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'class' ] = ( newAttributes[ 'class' ] or '' ) .. ' wikidata-snak' if hash then newAttributes[ 'data-wikidata-hash'] = hash else newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-main-snak' end return wrapValue( value, newAttributes ) end ---Wraps formatted statement value into HTML tag with attributes. ---@param value string value of statement ---@param propertyId string PID of property ---@param claimId string ID of claim or nil for local value ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapStatement( value, propertyId, claimId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'class' ] = newAttributes[ 'class' ] or '' newAttributes[ 'data-wikidata-property-id' ] = string.upper( propertyId ) if claimId then newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-claim' newAttributes[ 'data-wikidata-claim-id' ] = claimId else newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' no-wikidata' end return wrapValue( value, newAttributes ) end ---Wraps formatted qualifier's statement value into HTML tag with attributes. ---@param value string value of qualifier's statement ---@param qualifierId string PID of qualifier ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapQualifier( value, qualifierId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'data-wikidata-qualifier-id' ] = string.upper( qualifierId ) return wrapValue( value, newAttributes ) end ---Функция для получения сущности (еntity) для текущей страницы ---Подробнее о сущностях см. d:Wikidata:Glossary/ru ---@param id string Идентификатор (типа P18, Q42) ---@return table Таблица, элементы которой индексируются с нуля local function getEntityFromId( id ) local entity local wbStatus if id then wbStatus, entity = pcall( mw.wikibase.getEntity, id ) else wbStatus, entity = pcall( mw.wikibase.getEntity ) end return entity end ---Внутренняя функция для формирования сообщения об ошибке ---@param key string Ключ элемента в таблице config.errors (например entity-not-found) ---@return void local function throwError( key ) error( getConfig( 'errors', key ) ) end ---Функция для получения идентификатора сущностей ---@param value table ---@return string local function getEntityIdFromValue( value ) local prefix = '' if value[ 'entity-type' ] == 'item' then prefix = 'Q' elseif value[ 'entity-type' ] == 'property' then prefix = 'P' else throwError( 'unknown-entity-type' ) end return prefix .. value[ 'numeric-id' ] end ---Проверка на наличие специализированной функции в опциях ---@param options table ---@param prefix string ---@return function local function getUserFunction( options, prefix, defaultFunction ) -- проверка на указание специализированных обработчиков в параметрах, -- переданных при вызове if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then -- проверка на пустые строки в параметрах или их отсутствие if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then throwError( 'unknown-' .. prefix .. '-module' ) end -- динамическая загруза модуля с обработчиком указанным в параметре local formatter = require( 'Module:' .. options[ prefix .. '-module' ] ) if formatter == nil then throwError( prefix .. '-module-not-found' ) end local fun = formatter[ options[ prefix .. '-function' ] ] if fun == nil then throwError( prefix .. '-function-not-found' ) end return fun end return defaultFunction end ---Выбирает свойства по property id, дополнительно фильтруя их по рангу ---@param context table ---@param options table ---@param propertySelector string ---@return table | nil local function selectClaims( context, options, propertySelector ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entity is missing' ); end if not propertySelector then error( 'propertySelector not specified' ); end local result = WDS.load( options.entityId, propertySelector ) if not result or #result == 0 then return nil end if options.limit and options.limit ~= '' and options.limit ~= '-' then local limit = tonumber( options.limit, 10 ) while #result > limit do table.remove( result ) end end return result end ---Функция для получения значения свойства элемента в заданный момент времени. ---@param entityId string ---@param boundaries table Временные границы ---@param propertyIds table<string> ---@param selectors table<string> ---@return table Таблица соответствующих значений свойства local function getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ) if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type(entityId)); end local results = {} if not propertyIds or #propertyIds == 0 then return results end for i, propertyId in ipairs( propertyIds ) do local selector if selectors ~= nil then selector = selectors[ i ] or selectors[ propertyId ] or propertyId else selector = propertyId end local fakeAllClaims = {} fakeAllClaims[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId ) local filteredClaims = WDS.filter( fakeAllClaims, selector .. '[rank:preferred, rank:normal]' ) if filteredClaims then for _, claim in pairs( filteredClaims ) do if not boundaries then if not claim.qualifiers or not claim.qualifiers.P582 then table.insert( results, claim.mainsnak ) end else local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' ) local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' ) if ( startBoundaries == nil or startBoundaries[ 1 ] <= boundaries[ 1 ] ) and ( endBoundaries == nil or endBoundaries[ 1 ] >= boundaries[ 2 ] ) then table.insert( results, claim.mainsnak ) end end end end if #results > 0 then break end end return results end ---@param context table ---@param propertyId string ---@return table | nil function p.getTimeBoundariesFromProperty( context, propertyId ) local dateClaims = WDS.filter( context.entity.claims, propertyId ) if not dateClaims or #dateClaims == 0 then return nil; end -- only support exact date so far, but need improvment local left = nil local right = nil for _, claim in pairs( dateClaims ) do if not claim.mainsnak then return nil end local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak ) if not boundaries then return nil end left = min( left, boundaries[ 1 ] ) right = max( right, boundaries[ 2 ] ) end if not left or not right then return nil end return { left, right } end ---@param context table ---@param propertyIds table<string> ---@return table | nil function p.getTimeBoundariesFromProperties( context, propertyIds ) for _, propertyId in ipairs( propertyIds ) do local result = p.getTimeBoundariesFromProperty( context, propertyId ); if result then return result end end return nil end ---@param context table ---@param statement table ---@param qualifierId string ---@return table | nil function p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId ) -- only support exact date so far, but need improvement local left, right if statement.qualifiers and statement.qualifiers[ qualifierId ] then for _, qualifier in pairs( statement.qualifiers[ qualifierId ] ) do local boundaries = context.parseTimeBoundariesFromSnak( qualifier ) if not boundaries then return nil end left = min( left, boundaries[ 1 ] ) right = max( right, boundaries[ 2 ] ) end end if not left or not right then return nil end return { left, right } end ---@param _ table ---@param context table ---@param statement table ---@param qualifierIds table<string> ---@return table | nil function p.getTimeBoundariesFromQualifiers( _, context, statement, qualifierIds ) if not qualifierIds then qualifierIds = { 'P582', 'P580', 'P585' } end for _, qualifierId in pairs( qualifierIds ) do local result = p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId ) if result then return result end end return nil end ---@type table<string> local getLabelWithLang_DEFAULT_PROPERTIES = { 'P1813', 'P1448', 'P1705' } ---@type table<string> local getLabelWithLang_DEFAULT_SELECTORS = { 'P1813[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]', 'P1448[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]', 'P1705[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]' } ---Функция для получения метки элемента в заданный момент времени. ---@param context table ---@param options table ---@param entityId string ---@param boundaries table ---@param propertyIds table ---@param selectors table<string> ---@return string, string Текстовая метка элемента, язык метки local function getLabelWithLang( context, options, entityId, boundaries, propertyIds, selectors ) if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type( entityId ) ); end if not entityId then return nil end local langCode = CONTENT_LANGUAGE_CODE -- name from label local label if options.text and options.text ~= '' then label = options.text else if not propertyIds then propertyIds = getLabelWithLang_DEFAULT_PROPERTIES selectors = getLabelWithLang_DEFAULT_SELECTORS end -- name from properties local results = getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ) for _, result in pairs( results ) do if result.datavalue and result.datavalue.value then if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then label = result.datavalue.value.text langCode = result.datavalue.value.language break elseif result.datavalue.type == 'string' then label = result.datavalue.value break end end end if not label then label, langCode = mw.wikibase.getLabelWithLang( entityId ) if not langCode then return nil end end end return label, langCode end ---@param context table ---@param options table ---@return string local function formatPropertyDefault( context, options ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entityId missing' ); end local claims if options.property then -- TODO: Почему тут может не быть property? if options.rank then -- передать настройки ранга из конфига claims = context.selectClaims( options, options.property .. options.rank ) else claims = context.selectClaims( options, options.property ) end end if claims == nil then return '' --TODO error? end -- Обход всех заявлений утверждения и с накоплением оформленных предпочтительных -- заявлений в таблице local formattedClaims = {} for _, claim in pairs( claims ) do local formattedStatement = context.formatStatement( options, claim ) -- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil if formattedStatement and formattedStatement ~= '' then if not options.plain then formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id ) end table.insert( formattedClaims, formattedStatement ) end end -- создание текстовой строки со списком оформленых заявлений из таблицы local out = mw.text.listToText( formattedClaims, options.separator, options.conjunction ) if out ~= '' then if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end ---Create context ---@param initOptions table ---@return table | nil local function initContext( initOptions ) local context = { entityId = initOptions.entityId, entity = initOptions.entity, extractCategory = extractCategory, formatSnak = formatSnak, formatPropertyDefault = formatPropertyDefault, formatStatementDefault = formatStatementDefault, getPropertyInBoundaries = getPropertyInBoundaries, getTimeBoundariesFromProperty = p.getTimeBoundariesFromProperty, getTimeBoundariesFromProperties = p.getTimeBoundariesFromProperties, getTimeBoundariesFromQualifier = p.getTimeBoundariesFromQualifier, getTimeBoundariesFromQualifiers = p.getTimeBoundariesFromQualifiers, parseTimeFromSnak = p._parseTimeFromSnak, getLabelWithLang = getLabelWithLang, wrapSnak = wrapSnak, wrapStatement = wrapStatement, wrapQualifier = wrapQualifier, } context.cloneOptions = function( options ) local entity = options.entity options.entity = nil local newOptions = mw.clone( options ) options.entity = entity newOptions.entity = entity newOptions.frame = options.frame; -- На склонированном фрейме frame:expandTemplate() return newOptions end context.formatProperty = function( options ) local func = getUserFunction( options, 'property', context.formatPropertyDefault ) return func( context, options ) end context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end context.parseTimeBoundariesFromSnak = function( snak ) if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision then return p._parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision ) end return nil end context.getSourcingCircumstances = function( statement ) return getSourcingCircumstances( statement ) end context.selectClaims = function( options, propertyId ) return selectClaims( context, options, propertyId ) end return context end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@param options table ---@return string Formatted wikitext. local function formatProperty( options ) -- Получение сущности по идентификатору local entity = getEntityFromId( options.entityId ) if not entity then return -- throwError( 'entity-not-found' ) end -- проверка на присутсвие у сущности заявлений (claim) -- подробнее о заявлениях см. d:Викиданные:Глоссарий if not entity.claims then return '' --TODO error? end -- improve options options.frame = g_frame options.entity = entity options.extends = function( self, newOptions ) return copyTo( newOptions, copyTo( self, {} ) ) end if options.i18n then options.i18n = copyTo( options.i18n, copyTo( getConfig( 'i18n' ), {} ) ) else options.i18n = getConfig( 'i18n' ) end local context = initContext( options ) return context.formatProperty( options ) end ---Функция для оформления одного утверждения (statement) ---@param context table ---@param options table ---@param statement table ---@return string Formatted wikitext. function formatStatement( context, options, statement ) if not statement then error( 'statement is not specified or nil' ) end if not statement.type or statement.type ~= 'statement' then throwError( 'unknown-claim-type' ) end local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault ) return functionToCall( context, options, statement ) end ---@param statement table ---@return table function getSourcingCircumstances( statement ) if not statement then error( 'statement is not specified' ) end local circumstances = {} if statement.qualifiers and statement.qualifiers.P1480 then for _, qualifier in pairs( statement.qualifiers.P1480 ) do if qualifier and qualifier.datavalue and qualifier.datavalue.type == 'wikibase-entityid' and qualifier.datavalue.value and qualifier.datavalue.value[ 'entity-type'] == 'item' then table.insert( circumstances, qualifier.datavalue.value.id ) end end end return circumstances end ---Функция для оформления одного утверждения (statement) ---@param context table Context. ---@param options table Parameters. ---@param statement table ---@return string Formatted wikitext. function formatStatementDefault( context, options, statement ) if not context then error( 'context is not specified' ) end if not options then error( 'options is not specified' ) end if not statement then error( 'statement is not specified' ) end local circumstances = context.getSourcingCircumstances( statement ) options.qualifiers = statement.qualifiers local result = context.formatSnak( options, statement.mainsnak, circumstances ) if options.qualifier and statement.qualifiers and statement.qualifiers[ options.qualifier ] then local qualifierConfig = getPropertyParams( options.qualifier, nil, {} ) if options.i18n then qualifierConfig.i18n = options.i18n end if qualifierConfig.datatype == 'time' then qualifierConfig.nolinks = true end local qualifierValues = {} for _, qualifierSnak in pairs( statement.qualifiers[ options.qualifier ] ) do local snakValue = context.formatSnak( qualifierConfig, qualifierSnak ) if snakValue and snakValue ~= '' then table.insert( qualifierValues, snakValue ) end end if result and result ~= '' and #qualifierValues then if qualifierConfig.invisible then result = result .. table.concat( qualifierValues, ', ' ) else result = result .. ' (' .. table.concat( qualifierValues, ', ' ) .. ')' end end end if result and result ~= '' and options.references then result = result .. context.formatRefs( options, statement ) end return result end ---Функция для оформления части утверждения (snak) ---Подробнее о snak см. d:Викиданные:Глоссарий ---@param context table Context. ---@param options table Parameters. ---@param snak table ---@param circumstances table ---@return string Formatted wikitext. function formatSnak( context, options, snak, circumstances ) circumstances = circumstances or {} local result if snak.snaktype == 'somevalue' then if options[ 'somevalue' ] and options[ 'somevalue' ] ~= '' then result = options[ 'somevalue' ] else result = options.i18n[ 'somevalue' ] end elseif snak.snaktype == 'novalue' then if options[ 'novalue' ] and options[ 'novalue' ] ~= '' then result = options[ 'novalue' ] else result = options.i18n[ 'novalue' ] end elseif snak.snaktype == 'value' then result = formatDatavalue( context, options, snak.datavalue, snak.datatype ) for _, item in pairs( circumstances ) do if options.i18n[ item ] then result = options.i18n[ item ] .. result end end else throwError( 'unknown-snak-type' ) end if not result or result == '' then return nil end if options.plain then return result end return context.wrapSnak( result, snak.hash ) end ---Функция для оформления объектов-значений с географическими координатами ---@param value string Raw value. ---@param options table Parameters. ---@return string Formatted string. local function formatGlobeCoordinate( value, options ) -- проверка на требование в параметрах вызова на возврат сырого значения if options[ 'subvalue' ] == 'latitude' then -- широты return value[ 'latitude' ] elseif options[ 'subvalue' ] == 'longitude' then -- долготы return value[ 'longitude' ] elseif options[ 'nocoord' ] and options[ 'nocoord' ] ~= '' then -- если передан параметр nocoord, то не выводить координаты -- обычно это делается при использовании нескольких карточек на странице return '' else -- в противном случае формируются параметры для вызова шаблона {{coord}} -- нужно дописать в документации шаблона, что он отсюда вызывается, и что -- любое изменние его парамеров должно быть согласовано с кодом тут local coordModule = require( 'Module:Coordinates' ) local globe = options.globe or '' if globe == '' and value[ 'globe' ] then local globes = require( 'Module:Wikidata/Globes' ) globe = globes[ value[ 'globe' ] ] or '' end local display = 'inline' if options.display and options.display ~= '' then display = options.display elseif ( options.property:upper() == 'P625' ) then display = 'title' end local format = options.format or '' if format == '' then format = 'dms' if value[ 'precision' ] then local precision = value[ 'precision' ] * 60 if precision >= 60 then format = 'd' elseif precision >= 1 then format = 'dm' end end end g_frame.args = { tostring( value[ 'latitude' ] ), tostring( value[ 'longitude' ] ), globe = globe, type = options.type and options.type or '', scale = options.scale and options.scale or '', display = display, format = format, } return coordModule.coord(g_frame) end end ---Функция для оформления объектов-значений с файлами с Викисклада ---@param value string Raw value. ---@param options table Parameters. ---@return string Formatted string. local function formatCommonsMedia( value, options ) local image = value local caption = '' if options[ 'caption' ] and options[ 'caption' ] ~= '' then caption = options[ 'caption' ] end if caption ~= '' then caption = wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } ) end if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then -- если в value не содержится викикод или imagemap, то викифицируем имя файла -- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[phab:T28213]] image = '[[File:' .. value .. '|frameless' if options[ 'border' ] and options[ 'border' ] ~= '' then image = image .. '|border' end local size = options[ 'size' ] if size and size ~= '' then -- TODO: check localized pixel names too if not string.match( size, 'px$' ) then size = size .. 'px' end else size = fileDefaultSize end image = image .. '|' .. size if options[ 'alt' ] and options[ 'alt' ] ~= '' then image = image .. '|alt=' .. options[ 'alt' ] end if caption ~= '' then image = image .. '|' .. caption end image = image .. ']]' if caption ~= '' then image = image .. '<br>' .. caption end else image = image .. caption .. getCategoryByCode( 'media-contains-markup' ) end return image end ---Function for render math formulas ---@param value string Value. ---@param options table Parameters. ---@return string Formatted string. local function formatMath( value, options ) return options.frame:extensionTag{ name = 'math', content = value } end ---Функция для оформления внешних идентификаторов ---@param value string ---@param options table ---@return string local function formatExternalId( value, options ) local formatter = options.formatter local propertyId = options.property:upper() if not formatter or formatter == '' then local isGoodFormat = false local wbStatus, formatRegexStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1793' ) if wbStatus and formatRegexStatements then for _, statement in pairs( formatRegexStatements ) do if statement.mainsnak.snaktype == 'value' then local pattern = mw.ustring.gsub( statement.mainsnak.datavalue.value, '\\', '%' ) pattern = mw.ustring.gsub( pattern, '{%d+,?%d*}', '+' ) if ( string.find( pattern, '|' ) or string.find( pattern, '%)%?' ) or mw.ustring.match( value, '^' .. pattern .. '$' ) ~= nil ) then isGoodFormat = true break end end end end if isGoodFormat then local formatterStatements wbStatus, formatterStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1630' ) if wbStatus and formatterStatements then for _, statement in pairs( formatterStatements ) do if statement.mainsnak.snaktype == 'value' then formatter = statement.mainsnak.datavalue.value break end end end end end if formatter and formatter ~= '' then local encodedValue = mw.ustring.gsub( value, '%%', '%%%%' ) -- ломается, если подставить внутрь другого mw.ustring.gsub local link = mw.ustring.gsub( mw.ustring.gsub( formatter, '$1', encodedValue ), '.', { [ ' ' ] = '%20', [ '+' ] = '%2b', [ '[' ] = '%5B', [ ']' ] = '%5D' } ) local title = options.title if not title or title == '' then title = '$1' end title = mw.ustring.gsub( mw.ustring.gsub( title, '$1', encodedValue ), '.', { [ '[' ] = '(', [ ']' ] = ')' } ) return '[' .. link .. ' ' .. title .. ']' end return value end ---Функция для оформления числовых значений ---@param value table Объект-значение ---@param options table Таблица параметров ---@return string Оформленный текст local function formatQuantity( value, options ) -- диапазон значений local amount = string.gsub( value.amount, '^%+', '' ) local lang = mw.language.getContentLanguage() local langCode = lang:getCode() local function formatNum( number, sigfig ) local multiplier = '' if options.countByThousands then local powers = options.i18n.thousandPowers local pos = 1 while math.abs( number ) >= 1000 and pos < #powers do number = number / 1000 pos = pos + 1 end multiplier = powers[ pos ] if math.abs( number ) >= 100 then sigfig = sigfig or 0 elseif math.abs( number ) >= 10 then sigfig = sigfig or 1 else sigfig = sigfig or 2 end else sigfig = sigfig or 12 -- округление до 12 знаков после запятой, на 13-м возникает ошибка в точности end local iMultiplier = 10^sigfig number = math.floor( number * iMultiplier + 0.5 ) / iMultiplier return string.gsub( lang:formatNum( number ), '^-', '−' ) .. multiplier end local out = formatNum( tonumber( amount ) ) if value.upperBound then local diff = tonumber( value.upperBound ) - tonumber( amount ) if diff > 0 then -- временная провека, пока у большинства значений не будет убрано ±0 -- Пробуем понять до какого знака округлять local integer, dot, decimals, _ = value.upperBound:match( '^+?-?(%d*)(%.?)(%d*)(.*)' ) local precision if dot == '' then precision = -integer:match( '0*$' ):len() else precision = #decimals end local bound = formatNum( diff, precision ) if string.match( bound, 'E%-(%d+)' ) then -- если в экспоненциальном формате local digits = tonumber( string.match( bound, 'E%-(%d+)' ) ) - 2 bound = formatNum( diff * 10 ^ digits, precision ) bound = string.sub( bound, 0, 2 ) .. string.rep( '0', digits ) .. string.sub( bound, -string.len( bound ) + 2 ) end out = out .. ' ± ' .. bound end end if options.unit and options.unit ~= '' then if options.unit ~= '-' then out = out .. ' ' .. options.unit end elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' ) if unitEntityId ~= 'undefined' then local wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ) if wbStatus == true and unitEntity then if unitEntity.claims.P2370 and unitEntity.claims.P2370[ 1 ].mainsnak.snaktype == 'value' and not value.upperBound and options.siConversion == true then local conversionToSiUnit = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.amount, '^%+', '' ) if math.floor( math.log10( conversionToSiUnit ) ) ~= math.log10( conversionToSiUnit ) then -- Если не степени десятки (переводить сантиметры в метры не надо!) local outValue = tonumber( amount ) * conversionToSiUnit if outValue > 0 then -- Пробуем понять до какого знака округлять local integer, dot, decimals, _ = amount:match( '^(%d*)(%.?)(%d*)(.*)' ) local precision if dot == '' then precision = -integer:match( '0*$' ):len() else precision = #decimals end local adjust = math.log10( math.abs( conversionToSiUnit ) ) + math.log10( 2 ) local minPrecision = 1 - math.floor( math.log10( outValue ) + 2e-14 ) out = formatNum( outValue, math.max( math.floor( precision + adjust ), minPrecision ) ) else out = formatNum( outValue, 0 ) end unitEntityId = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.unit, 'http://www.wikidata.org/entity/', '' ) wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ) end end local label = getLabelWithLang( context, options, unitEntity.id, nil, { "P5061", "P558", "P558" }, { 'P5061[language:' .. langCode .. ']', 'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']', 'P558[!P282][!P407]' } ) out = out .. ' ' .. label end end end return out end ---Функция для оформления URL ---@param context table ---@param options table ---@param value string local function formatUrlValue( context, options, value ) if not options.length or options.length == '' then options.length = 25 end local moduleUrl = require( 'Module:URL' ) return moduleUrl.formatUrlSingle( context, options, value ) end local DATATYPE_CACHE = {} ---Get property datatype by ID. ---@param propertyId string Property ID, e.g. 'P123'. ---@return string Property datatype, e.g. 'commonsMedia', 'time' or 'url'. local function getPropertyDatatype( propertyId ) if not propertyId or not string.match( propertyId, '^P%d+$' ) then return nil end local cached = DATATYPE_CACHE[ propertyId ] if cached ~= nil then return cached end local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, propertyId ) if wbStatus ~= true or not propertyEntity then return nil end mw.log("Loaded datatype " .. propertyEntity.datatype .. " of " .. propertyId .. ' from wikidata, consider passing datatype argument to formatProperty call or to Wikidata/config' ) DATATYPE_CACHE[ propertyId ] = propertyEntity.datatype return propertyEntity.datatype end ---@param datavalue table ---@return function local function getPlainValueFunction( datavalue, _ ) if datavalue.type == 'wikibase-entityid' then return function( _, _, value ) return getEntityIdFromValue( value ) end elseif datavalue.type == 'string' then return function( _, _, value ) return value end elseif datavalue.type == 'monolingualtext' then return function( _, _, value ) return value.text end elseif datavalue.type == 'globecoordinate' then return function( _, _, value ) return value.latitude .. ',' .. value.longitude end elseif datavalue.type == 'quantity' then return function( _, _, value ) return value.amount end elseif datavalue.type == 'time' then return function( _, _, value ) return value.time end end throwError( 'unknown-datavalue-type' ) end ---@param datavalue table ---@param datatype string ---@return function local function getDefaultValueFunction( datavalue, datatype ) -- вызов обработчиков по умолчанию для известных типов значений if datavalue.type == 'wikibase-entityid' then -- Entity ID return function( context, options, value ) return formatEntityId( context, options, getEntityIdFromValue( value ) ) end elseif datavalue.type == 'string' then -- String if datatype and datatype == 'commonsMedia' then -- Media return function( _, options, value ) return formatCommonsMedia( value, options ) end elseif datatype and datatype == 'external-id' then -- External ID return function( _, options, value ) return formatExternalId( value, options ) end elseif datatype and datatype == 'math' then -- Math formula return function( _, options, value ) return formatMath( value, options ) end elseif datatype and datatype == 'url' then -- URL return formatUrlValue end return function( _, _, value ) return value end elseif datavalue.type == 'monolingualtext' then -- моноязычный текст (строка с указанием языка) return function( _, options, value ) if options.monolingualLangTemplate == 'lang' then if value.language == CONTENT_LANGUAGE_CODE then return value.text end return options.frame:expandTemplate{ title = 'lang-' .. value.language, args = { value.text } } elseif options.monolingualLangTemplate == 'ref' then return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language } else return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' end end elseif datavalue.type == 'globecoordinate' then -- географические координаты return function( _, options, value ) return formatGlobeCoordinate( value, options ) end elseif datavalue.type == 'quantity' then return function( _, options, value ) return formatQuantity( value, options ) end elseif datavalue.type == 'time' then return function( context, options, value ) local moduleDate = require( 'Module:Wikidata/date' ) return moduleDate.formatDate( context, options, value ) end end -- во всех стальных случаях возвращаем ошибку throwError( 'unknown-datavalue-type' ) end ---Функция для оформления значений (value) ---Подробнее о значениях см. d:Wikidata:Glossary/ru ---@param context table ---@param options table ---@param datavalue table ---@param datatype string ---@return string Оформленный текст function formatDatavalue( context, options, datavalue, datatype ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not datavalue then error( 'datavalue not specified' ); end if not datavalue.value then error( 'datavalue.value is missing' ); end -- проверка на указание специализированных обработчиков в параметрах, -- переданных при вызове if options.plain then context.formatValueDefault = getPlainValueFunction( datavalue, datatype ) else context.formatValueDefault = getDefaultValueFunction( datavalue, datatype ) end local functionToCall = getUserFunction( options, 'value', context.formatValueDefault ) return functionToCall( context, options, datavalue.value ) end local DEFAULT_BOUNDARIES = { os.time() * 1000, os.time() * 1000} ---Функция для оформления идентификатора сущности ---@param context table ---@param options table ---@param entityId string ---@return string Оформленный текст function formatEntityId( context, options, entityId ) -- получение локализованного названия local boundaries if options.qualifiers then boundaries = p.getTimeBoundariesFromQualifiers( context.frame, context, { qualifiers = options.qualifiers } ) end if not boundaries then boundaries = DEFAULT_BOUNDARIES end local label, labelLanguageCode = getLabelWithLang( context, options, entityId, boundaries ) -- определение соответствующей показываемому элементу категории local category = context.extractCategory( options, { id = entityId } ) -- получение ссылки по идентификатору local link = mw.wikibase.sitelink( entityId ) if link then -- ссылка на категорию, а не добавление страницы в неё if mw.ustring.match( link, '^' .. mw.site.namespaces[ 14 ].name .. ':' ) then link = ':' .. link end if label and not options.rawArticle then if labelLanguageCode ~= CONTENT_LANGUAGE_CODE then label = '<span lang="' .. label .. '">' .. label .. '</span>' end local a = '[[' .. link .. '|' .. label .. ']]' if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then a = a .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' ) end return a .. category else return '[[' .. link .. ']]' .. category end end if label then -- TODO: возможно, лучше просто mw.wikibase.getLabel(entityId) -- красная ссылка -- TODO: разобраться, почему не всегда есть options.frame local moduleRedLink = require( 'Module:Wikidata/redLink' ) local title = mw.title.new( label ) if title and not title.exists and options.frame then local rawLabel = mw.wikibase.getLabel(entityId) or label -- без |text= и boundaries; or label - костыль local redLink = moduleRedLink.formatRedLinkWithInfobox(rawLabel, label, entityId) if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then redLink = '<span lang="' .. labelLanguageCode .. '">' .. redLink .. '</span>' .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' ) end return redLink .. category end -- TODO: перенести до проверки на существование статьи local addWdLink = false if ( not options.format or options.format ~= 'text' ) and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: переписать на format=text then addWdLink = true end -- одноимённая статья уже существует - выводится текст и ссылка на ВД return moduleRedLink.formatText(label, entityId, addWdLink) .. category end -- сообщение об отсутвии локализованного названия -- not good, but better than nothing return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. getCategoryByCode( 'links-to-entities-with-missing-label' ) .. category end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@deprecated Use p.formatProperty() instead ---@param frame table ---@return string Строка оформленного текста, предназначенная для отображения в статье function p.formatStatements( frame ) return p.formatProperty( frame ) end ---Получение параметров, которые обычно используются для вывода свойства. ---@param propertyId string ---@param datatype string ---@param params table function getPropertyParams( propertyId, datatype, params ) local config = getConfig() -- Различные уровни настройки параметров, по убыванию приоритета local propertyParams = {} -- 1. Параметры, указанные явно при вызове if params then for key, value in pairs( params ) do if value ~= '' then propertyParams[ key ] = value end end end if toBoolean( propertyParams.plain, false ) then propertyParams.separator = propertyParams.separator or ', ' propertyParams.conjunction = propertyParams.conjunction or ', ' else -- 2. Настройки конкретного параметра if config.properties and config.properties[ propertyId ] then for key, value in pairs( config.properties[ propertyId ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end -- 3. Указанный пресет настроек if propertyParams.preset and config.presets and config.presets[ propertyParams.preset ] then for key, value in pairs( config.presets[ propertyParams.preset ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end datatype = datatype or params.datatype or propertyParams.datatype or getPropertyDatatype( propertyId ) if propertyParams.datatype == nil then propertyParams.datatype = datatype end -- 4. Настройки для типа данных if datatype and config.datatypes and config.datatypes[ datatype ] then for key, value in pairs( config.datatypes[ datatype ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end -- 5. Общие настройки для всех свойств if config.global then for key, value in pairs( config.global ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end end return propertyParams end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@param frame table ---@return string Строка оформленного текста, предназначенная для отображения в статье function p.formatProperty( frame ) local args = copyTo( frame.args, {} ) -- проверка на отсутствие обязательного параметра property if not args.property then throwError( 'property-param-not-provided' ) end local override local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '([^Pp0-9].*)$', function(w) if string.sub( w, 1, 1 ) == '~' then override = w end return '' end ) ) if override then args[ override:match( '[,~]([^=]*)=' ) ] = override:match( '=(.*)' ) args.property = propertyId end -- проброс всех параметров из шаблона {wikidata} и параметра from откуда угодно local p_frame = frame while p_frame do if p_frame:getTitle() == mw.site.namespaces[ 10 ].name .. ':Wikidata' then copyTo( p_frame.args, args, true ) end if p_frame.args and p_frame.args.from and p_frame.args.from ~= '' then args.entityId = p_frame.args.from else args.entityId = mw.wikibase.getEntityIdForCurrentPage() end p_frame = p_frame:getParent() end args = getPropertyParams( propertyId, nil, args ) local datatype = args.datatype -- перевод итоговых значений флагов в true/false и добавление значений -- по умолчанию только в том случае, если они нигде не были указаны ранее args.plain = toBoolean( args.plain, false ) args.nocat = not args.plain and toBoolean( args.nocat, false ) args.references = not args.plain and toBoolean( args.references, true ) -- если значение передано в параметрах вызова то выводим только его if args.value and args.value ~= '' then -- специальное значение для скрытия Викиданных if args.value == '-' then return '' end local value = args.value -- опция, запрещающая оформление значения, поэтому никак не трогаем if args.plain then return value end local context = initContext( args ) -- обработчики по типу значения local wrapperExtraArgs = {} if args[ 'value-module' ] and args[ 'value-function' ] and not string.find( value, '[%[%]%{%}]' ) then local func = getUserFunction( args, 'value' ) value = func( context, args, value ) elseif datatype == 'commonsMedia' then value = formatCommonsMedia( value, args ) elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then wrapperExtraArgs[ 'data-wikidata-external-id' ] = mw.text.killMarkers( value ) value = formatExternalId( value, args ) --elseif datatype == 'math' then -- args.frame = frame -- костыль: в formatMath нужно frame:extensionTag -- value = formatMath( value, args ) elseif datatype == 'url' then value = formatUrlValue( context, args, value ) end -- оборачиваем в тег для JS-функций if string.match( propertyId, '^P%d+$' ) then value = mw.text.trim( value ) -- временная штрафная категория для исправления табличных вставок local allowTables = getPropertyParams( propertyId, nil, {} ).allowTables if not allowTables and string.match( value, '<t[dhr][ >]' ) -- and not string.match( value, '<table[ >]' ) -- and not string.match( value, '^%{%|' ) then value = value .. getCategoryByCode( 'value-contains-table', propertyId ) else value = wrapStatement( value, propertyId, nil, wrapperExtraArgs ) end end return value end -- ability to disable loading Wikidata if args.entityId == '-' then return '' end g_frame = frame -- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений) return formatProperty( args ) end ---Функция проверки на присутствие источника в списке нерекомендованных. ---@param snaks table ---@return boolean local function isReferenceDeprecated( snaks ) if not snaks then return false end if snaks.P248 and snaks.P248[ 1 ] and snaks.P248[ 1 ].datavalue and snaks.P248[ 1 ].datavalue.value.id then local entityId = snaks.P248[ 1 ].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end elseif snaks.P1433 and snaks.P1433[ 1 ] and snaks.P1433[ 1 ].datavalue and snaks.P1433[ 1 ].datavalue.value.id then local entityId = snaks.P1433[ 1 ].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end end return false end ---Функция оформления ссылок на источники (reference) ---Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru --- ---Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context ---Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства). ---@param context table ---@param options table ---@param statement table ---@return string Оформленные примечания для отображения в статье function formatRefs( context, options, statement ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entityId missing' ); end if not statement then error( 'statement not specified' ); end if not outputReferences then return '' end ---@type string[] local references = {} if statement.references then local hasNotDeprecated = false local displayCount = 0 for _, reference in pairs( statement.references ) do if not isReferenceDeprecated( reference.snaks ) then hasNotDeprecated = true end end for _, reference in pairs( statement.references ) do local display = true if hasNotDeprecated then if isReferenceDeprecated( reference.snaks ) then display = false end end if displayCount >= 2 then if options.entityId and options.property then local propertyId = mw.ustring.match( options.property, '^[Pp][0-9]+' ) -- TODO: обрабатывать не тут, а раньше local moreReferences = '<sup>[[d:' .. options.entityId .. '#' .. string.upper( propertyId ) .. '|[…]]]</sup>' table.insert( references, moreReferences ) end break end if display == true then ---@type string local refText = moduleSources.renderReference( g_frame, options.entityId, reference ) if refText and refText ~= '' then table.insert( references, refText ) displayCount = displayCount + 1 end end end end return table.concat( references ) end return p 4558f762f30c6ebfb9f5333dbd7ebda83c6873f2 Модуль:Wikidata/media 828 88 186 2024-10-26T15:20:21Z wikipedia, ruwikipedia>Stjn 0 [[ВП:×|отмена]]: сломало отображение в множестве статей Scribunto text/plain local p = {} -- Константы local contentLanguageCode = mw.getContentLanguage():getCode(); function p.formatCommonsCategory( context, options, value ) local link = 'commons:Category:' .. value local title = value .. ' на Викискладе' if ( options['text'] and options['text'] ~= '' ) then title = options['text'] end commons = '[[' .. link .. '|' .. title .. ']]' --Commons icon if ( not options['icon'] or options['icon'] ~= '-' ) then local icon_size = '15px' if ( options['icon_size'] and options['icon_size'] ~= '' ) then icon_size = options['icon_size'] end commons = '[[File:Commons-logo.svg|' .. icon_size .. '|link=' .. link .. '|alt=Логотип Викисклада]] ' .. commons end --Text before and after link if ( options['text_before'] and options['text_before'] ~= '' ) then if ( options['text_before'] ~= '-' ) then commons = options['text_before'] .. ' ' .. commons end end if ( options['text_after'] and options['text_after'] ~= '' ) then if ( options['text_after'] ~= '-' ) then commons = commons .. ' ' .. options['text_after'] end end return commons end --[[ Временный хак, нужно добавить config, getConfig и getCategoryByCode в options, чтобы они были доступны в любом месте кода. ]] local config; local function getCategoryByCode( code, sortkey ) if config == nil then config = require( 'Module:Wikidata/config' ); end; local value = config[ 'categories' ][ code ]; if not value or value == '' then return ''; end return '[[Category:' .. value .. ']]'; end local function getCaption( context, options ) local caption = '' if options.qualifiers and options.qualifiers.P2096 then for i, qualifier in pairs( options.qualifiers.P2096 ) do if ( qualifier and qualifier.datavalue and qualifier.datavalue.type == 'monolingualtext' and qualifier.datavalue.value and qualifier.datavalue.value.language == contentLanguageCode ) then caption = qualifier.datavalue.value.text break end end end if options['appendTimestamp'] and options.qualifiers and options.qualifiers.P585 and options.qualifiers.P585[1] then local moment = context.formatValueDefault( context, options, options.qualifiers.P585[1].datavalue ) if not caption or caption == '' then caption = moment else caption = caption .. ', ' .. moment end end local localValue = ''; if options[ 'value' ] and options[ 'value' ] ~= '' then localValue = options[ 'value' ]; end local localCaption = ''; if options[ 'caption' ] and options[ 'caption' ] ~= '' then localCaption = options[ 'caption' ]; end if localValue ~= '' then caption = localCaption; end local formattedCaption = '' if caption ~= '' then formattedCaption = context.wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } ); end if localValue == '' and localCaption ~= '' then formattedCaption = formattedCaption .. getCategoryByCode( 'media-contains-local-caption' ) if options.frame:preprocess('{{REVISIONID}}') == '' then formattedCaption = formattedCaption .. '<span class="error" style="font-size:94%;">Локальная подпись не используется, потому что изображение берётся из Викиданных, см. [[Википедия:Шаблоны-карточки#Описание изображения в Викиданных|здесь]]</span>' end end return caption, formattedCaption end function p.formatCommonsMediaValue( context, options, value ) local image = value; local caption, formattedCaption = getCaption( context, options ) if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then -- если в value не содержится викикод или imagemap, то викифицируем имя файла -- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[PHAB:T28213]] image = '[[File:' .. value .. '|frameless'; if options[ 'border' ] and options[ 'border' ] ~= '' then image = image .. '|border'; end local size = options[ 'size' ]; if size and size ~= '' then if not string.match( size, 'px$' ) and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики then size = size .. 'px' end -- временно if string.match( size, 'pxpx' ) then image = '[[Категория:Википедия:Изображение с pxpx в размере]]' .. image end else size = fileDefaultSize; end image = image .. '|' .. size; if options[ 'alt' ] and options[ 'alt' ] ~= '' then image = image .. '|alt=' .. options[ 'alt' ]; end if caption ~= '' then image = image .. '|' .. caption end image = image .. ']]'; if formattedCaption ~= '' then image = image .. '<br>' .. formattedCaption; end else image = image .. formattedCaption .. getCategoryByCode( 'media-contains-markup' ); end if options.entity and options.fixdouble then local page = mw.title.getCurrentTitle() local txt = page:getContent() if txt and txt:match(':' .. value) and mw.title.getCurrentTitle():inNamespace(0) then if options.frame:preprocess('{{REVISIONID}}') == '' then image = image .. '<span class="error">Это изображение встречается ниже по тексту статьи; пожалуйста, уберите одну из копий (не потеряв при этом подпись)</span>' end image = image .. getCategoryByCode( 'media-contains-local-double' ) end end return image end return p ec384e72491465f4103cce95a8f9467df428a432 Модуль:String 828 27 64 2024-11-18T02:41:06Z wikipedia, ruwikipedia>Stjn 0 аналогично английскому разделу — mw.ustring.gsub тут не нужен Scribunto text/plain --[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 'true' or 1, any error condition will result in an empty string being returned rather than an error message. error_category: If an error occurs, specifies the name of a category to include with the error message. The default category is [Category:Errors reported by Module String]. no_category: If set to 'true' or 1, no category will be added if an error is generated. Unit tests for this module are available at Module:String/tests. ]] local str = {} --[[ subcount This function returns the count of substring in source string. Usage: {{#invoke:String|subcount|source_string|substring|plain_flag}} OR {{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}} Parameters s: The string to search pattern: The pattern or string to find within the string plain: A flag indicating that the substring should be understood as plain text. Defaults to true. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.subcount( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} ); local s = new_args['s'] or ''; local plain_flag = str._getBoolean( new_args['plain'] or true ); local pattern = new_args['pattern'] or ''; if s == '' or pattern == '' then return 0; end if plain_flag then pattern = str._escapePattern( pattern ); end local _, count = mw.ustring.gsub(s, pattern, "") return count; end --[[ len This function returns the length of the target string. Usage: {{#invoke:String|len|target_string|}} OR {{#invoke:String|len|s=target_string}} Parameters s: The string whose length to report If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.len( frame ) local new_args = str._getParameters( frame.args, {'s'} ); local s = new_args['s'] or ''; return mw.ustring.len( s ) end --[[ sub This function returns a substring of the target string at specified indices. Usage: {{#invoke:String|sub|target_string|start_index|end_index}} OR {{#invoke:String|sub|s=target_string|i=start_index|j=end_index}} Parameters s: The string to return a subset of i: The fist index of the substring to return, defaults to 1. j: The last index of the string to return, defaults to the last character. The first character of the string is assigned an index of 1. If either i or j is a negative value, it is interpreted the same as selecting a character by counting from the end of the string. Hence, a value of -1 is the same as selecting the last character of the string. If the requested indices are out of range for the given string, an error is reported. ]] function str.sub( frame ) local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } ); local s = new_args['s'] or ''; local i = tonumber( new_args['i'] ) or 1; local j = tonumber( new_args['j'] ) or -1; local len = mw.ustring.len( s ); -- Convert negatives for range checking if i < 0 then i = len + i + 1; end if j < 0 then j = len + j + 1; end if i > len or j > len or i < 1 or j < 1 then return str._error( 'Значение индекса подстроки выходит за допустимые границы' ); end if j < i then return str._error( 'Неверный порядок индексов подстроки' ); end return mw.ustring.sub( s, i, j ) end --[[ This function implements that features of {{str sub old}} and is kept in order to maintain these older templates. ]] function str.sublength( frame ) local i = tonumber( frame.args.i ) or 0 local len = tonumber( frame.args.len ) return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) end --[[ match This function returns a substring from the source string that matches a specified pattern. Usage: {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} OR {{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index |match=match_number|plain=plain_flag|nomatch=nomatch_output}} Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from each string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. If the match_number or start_index are out of range for the string being queried, then this function generates an error. An error is also generated if no match is found. If one adds the parameter ignore_errors=true, then the error will be suppressed and an empty string will be returned on any failure. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] function str.match( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} ); local s = new_args['s'] or ''; local start = tonumber( new_args['start'] ) or 1; local plain_flag = str._getBoolean( new_args['plain'] or false ); local pattern = new_args['pattern'] or ''; local match_index = math.floor( tonumber(new_args['match']) or 1 ); local nomatch = new_args['nomatch']; if s == '' then return str._error( 'Пустая строка поиска' ); end if pattern == '' then return str._error( 'Пустой шаблон поиска' ); end if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then return str._error( 'Индекс начала поиска выходит за допустимые границы' ); end if match_index == 0 then return str._error( 'Индекс совпадения выходит за допустимые границы' ); end if plain_flag then pattern = str._escapePattern( pattern ); end local result if match_index == 1 then -- Find first match is simple case result = mw.ustring.match( s, pattern, start ) else if start > 1 then s = mw.ustring.sub( s, start ); end local iterator = mw.ustring.gmatch(s, pattern); if match_index > 0 then -- Forward search for w in iterator do match_index = match_index - 1; if match_index == 0 then result = w; break; end end else -- Reverse search local result_table = {}; local count = 1; for w in iterator do result_table[count] = w; count = count + 1; end result = result_table[ count + match_index ]; end end if result == nil then if nomatch == nil then return str._error( 'Совпадение не найдено' ); else return nomatch; end else return result; end end --[[ pos This function returns a single character from the target string at position pos. Usage: {{#invoke:String|pos|target_string|index_value}} OR {{#invoke:String|pos|target=target_string|pos=index_value}} Parameters target: The string to search pos: The index for the character to return If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. The first character has an index value of 1. If one requests a negative value, this function will select a character by counting backwards from the end of the string. In other words pos = -1 is the same as asking for the last character. A requested value of zero, or a value greater than the length of the string returns an error. ]] function str.pos( frame ) local new_args = str._getParameters( frame.args, {'target', 'pos'} ); local target_str = new_args['target'] or ''; local pos = tonumber( new_args['pos'] ) or 0; if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then return str._error( 'Значение индекса строки выходит за допустимые границы' ); end return mw.ustring.sub( target_str, pos, pos ); end --[[ str_find This function duplicates the behavior of {{str_find}}, including all of its quirks. This is provided in order to support existing templates, but is NOT RECOMMENDED for new code and templates. New code is recommended to use the "find" function instead. Returns the first index in "source" that is a match to "target". Indexing is 1-based, and the function returns -1 if the "target" string is not present in "source". Important Note: If the "target" string is empty / missing, this function returns a value of "1", which is generally unexpected behavior, and must be accounted for separatetly. ]] function str.str_find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target'} ); local source_str = new_args['source'] or ''; local target_str = new_args['target'] or ''; if target_str == '' then return 1; end local start = mw.ustring.find( source_str, target_str, 1, true ) if start == nil then start = -1 end return start end --[[ find This function allows one to search for a target string or pattern within another string. Usage: {{#invoke:String|find|source_str|target_string|start_index|plain_flag}} OR {{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}} Parameters source: The string to search target: The string or pattern to find within source start: The index within the source string to start the search, defaults to 1 plain: Boolean flag indicating that target should be understood as plain text and not as a Lua style regular expression, defaults to true If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. This function returns the first index >= "start" where "target" can be found within "source". Indices are 1-based. If "target" is not found, then this function returns 0. If either "source" or "target" are missing / empty, this function also returns 0. This function should be safe for UTF-8 strings. ]] function str.find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['target'] or ''; local start_pos = tonumber(new_args['start']) or 1; local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return 0; end plain = str._getBoolean( plain ); local start = mw.ustring.find( source_str, pattern, start_pos, plain ) if start == nil then start = 0 end return start end --[[ replace This function allows one to replace a target string or pattern within another string. Usage: {{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}} OR {{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string| count=replacement_count|plain=plain_flag}} Parameters source: The string to search pattern: The string or pattern to find within source replace: The replacement text count: The number of occurences to replace, defaults to all. plain: Boolean flag indicating that pattern should be understood as plain text and not as a Lua style regular expression, defaults to true ]] function str.replace( frame ) local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['pattern'] or ''; local replace = new_args['replace'] or ''; local count = tonumber( new_args['count'] ); local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return source_str; end plain = str._getBoolean( plain ); if plain then pattern = str._escapePattern( pattern ); replace = string.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences. end local result; if count ~= nil then result = mw.ustring.gsub( source_str, pattern, replace, count ); else result = mw.ustring.gsub( source_str, pattern, replace ); end return result; end --[[ This function adds support for escaping parts of the patterns when using [plain=false]. ]] function str.escape( frame ) local new_args = str._getParameters( frame.args, {'pattern' } ); local pattern = new_args['pattern'] or ''; local result = ''; result = str._escapePattern( pattern ); return result; end --[[ Internal compare string function ]] function str._strcmp(a , b) local s1c = mw.ustring.gcodepoint( a ); local s2c = mw.ustring.gcodepoint( b ); while true do local c1 = s1c(); local c2 = s2c(); if c1 == nil then if c2 == nil then return 0 else return -1 end else if c2 ~= nil then if c1 ~= c2 then return c1 < c2 and -1 or 1 end else return 1 end end end return 0 end --[[ compare This function compare two UTF-8 strings Usage: {{#invoke:String|compare|str1|str2}} Returns: 0 - if strings are equal 1 - if st1 > str2 -1 - if str1 < str2 ]] function str.compare(frame) local str1 = frame.args[1] or ''; local str2 = frame.args[2] or ''; return str._strcmp(str1 , str2) end --[[ simple function to pipe string.rep to templates. ]] function str.rep( frame ) local repetitions = tonumber( frame.args[2] ) if not repetitions then return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' ) end return string.rep( frame.args[1] or '', repetitions ) end --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function str._getParameters( frame_args, arg_list ) local new_args = {}; local index = 1; local value; for i,arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index]; index = index + 1; end new_args[arg] = value; end return new_args; end --[[ Helper function to handle error messages. ]] function str._error( error_str ) local frame = mw.getCurrentFrame(); local error_category = frame.args.error_category or 'Страницы с ошибками модуля String'; local ignore_errors = frame.args.ignore_errors or false; local no_category = frame.args.no_category or false; if str._getBoolean(ignore_errors) then return ''; end local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>'; if error_category ~= '' and not str._getBoolean( no_category ) then error_str = '[[Категория:' .. error_category .. ']]' .. error_str; end return error_str; end --[[ Helper Function to interpret boolean strings ]] function str._getBoolean( boolean_str ) local boolean_value; if type( boolean_str ) == 'string' then boolean_str = boolean_str:lower(); if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' or boolean_str == '' then boolean_value = false; else boolean_value = true; end elseif type( boolean_str ) == 'boolean' then boolean_value = boolean_str; else error( 'Логическое значение не найдено' ); end return boolean_value end --[[ Helper function that escapes all pattern characters so that they will be treated as plain text. ]] function str._escapePattern( pattern_str ) return ( string.gsub( pattern_str, "[%(%)%.%%%+%-%*%?%[%^%$%]]", "%%%0" ) ) end return str 2c7347f1dafbbc0efc196c148a1f81e7b82420dc Модуль:Wikidata/config 828 85 180 2024-12-15T07:54:37Z wikipedia, ruwikipedia>Putnik 0 на всякий случай, чтобы избежать ненужных сносок Scribunto text/plain -- Property configuration for Wikidata module return { global = { separator = ',&#32;', conjunction = '&#32;и&#32;', }, presets = { ['catonly'] = { datatype = 'wikibase-item', conjunction = '', invisible = true, ['value-module'] = 'Wikidata/item', ['value-function'] = 'formatCategoryOnly', references = '', category = 'P910', }, ['country'] = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/Places', ['claim-function'] = 'formatCountryClaimWithFlag', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['from-to'] = { datatype = 'time', ['property-module'] = 'Wikidata/date', ['property-function'] = 'formatDateIntervalProperty', }, ['link'] = { ['value-module'] = 'Wikidata/link', ['value-function'] = 'fromModule', }, ['list'] = { before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['name'] = { datatype = 'monolingualtext', monolingualLangTemplate = 'lang', separator = '<br>', conjunction = '<br>', }, ['place'] = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/Places', ['claim-function'] = 'formatPlaceWithQualifiers', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['quantity (date)'] = { datatype = 'quantity', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', qualifier = 'P585', }, }, datatypes = { commonsMedia = { limit = 1, references = false, size = '274x400px', separator = '<br>', conjunction = '<br>', somevalue = '', ['value-module'] = 'Wikidata/media', ['value-function'] = 'formatCommonsMediaValue', }, ['external-id'] = { references = false, }, ['globe-coordinate'] = { limit = 1, references = false, }, url = { separator = '<br>', conjunction = '<br>', references = false, ['value-module'] = 'Wikidata/url', ['value-function'] = 'formatUrlValue', }, quantity = { siConversion = true } }, properties = { P6 = { datatype = 'wikibase-item', }, P17 = { preset = 'country', }, P18 = { datatype = 'commonsMedia', fixdouble = true, }, P19 = { preset = 'place', separator = ',</li><li>', conjunction = ' или </li><li>', }, P20 = { preset = 'place', separator = ',</li><li>', conjunction = ' или </li><li>', }, P22 = { datatype = 'wikibase-item', conjunction = ' или ' }, P25 = { datatype = 'wikibase-item', conjunction = ' или ' }, P26 = { datatype = 'wikibase-item', }, P27 = { preset = 'country', }, P31 = { datatype = 'wikibase-item', references = false, }, P37 = { datatype = 'wikibase-item', }, P39 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/positions', ['claim-function'] = 'formatPositionClaim', separator = '', conjunction = '', allowTables = true, }, P40 = { datatype = 'wikibase-item', }, P41 = { datatype = 'commonsMedia', size = '150x200px', }, P53 = { datatype = 'wikibase-item', category = 'P910', }, P54 = { category = 'P6112', }, P57 = { datatype = 'wikibase-item', preset = 'list', }, P58 = { datatype = 'wikibase-item', preset = 'list', }, P59 = { datatype = 'wikibase-item', category = 'P910', references = false, }, P69 = { datatype = 'wikibase-item', preset = 'list', category = 'P3876', qualifier = 'P582', }, P94 = { datatype = 'commonsMedia', size = '100x200px', }, P86 = { datatype = 'wikibase-item', preset = 'list', }, P101 = { datatype = 'wikibase-item', }, P102 = { datatype = 'wikibase-item', preset = 'list', qualifier = 'P582', category = 'P6365', }, P103 = { datatype = 'wikibase-item', }, P106 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'formatEntityWithGenderClaim', conjunction = ',&#32;', }, P108 = { datatype = 'wikibase-item', preset = 'list', category = 'P4195', }, P109 = { datatype = 'commonsMedia', size = '150x150px', alt = 'Изображение автографа', }, P117 = { datatype = 'commonsMedia', size = '290x300px', alt = 'Изображение химической структуры', }, P119 = { preset = 'place', thisLocationOnly = 'true', }, P131 = { datatype = 'wikibase-item', }, P140 = { datatype = 'wikibase-item', }, P154 = { size = '220x80px', alt = 'Изображение логотипа', }, P159 = { preset = 'place', }, P161 = { preset = 'list', }, P162 = { preset = 'list', }, P163 = { datatype = 'wikibase-item', }, P166 = { datatype = 'wikibase-item', ['property-module'] = 'Wikidata/Medals', ['property-function'] = 'formatProperty', ['value-module'] = 'Wikidata/Medals', ['value-function'] = 'formatValue', before = '<div style="text-align:justify">', after = '</div>', separator = '&#32;', conjunction = '&#32;', references = false, allowTables = true, }, P190 = { datatype = 'wikibase-item', }, P212 = { preset = 'link', }, P225 = { preset = 'list', ['claim-module'] = 'Wikidata/Biology', ['claim-function'] = 'formatTaxonNameClaim', }, P237 = { datatype = 'wikibase-item', }, P241 = { datatype = 'wikibase-item', }, P242 = { datatype = 'commonsMedia', size = '300x300px', }, P247 = { formatter = 'https://nssdc.gsfc.nasa.gov/nmc/spacecraft/display.action?id=$1', }, P267 = { preset = 'link', }, P276 = { preset = 'place', }, P281 = { datatype = 'string', }, P286 = { preset = 'list', }, P296 = { formatter = 'http://osm.sbin.ru/esr/esr:$1', }, P301 = { rawArticle = true, }, P344 = { preset = 'list', }, P345 = { preset = 'link', }, P348 = { preset = 'list', ['property-module'] = 'Wikidata/Software', ['property-function'] = 'formatVersionProperty', }, P361 = { datatype = 'wikibase-item', }, P373 = { datatype = 'string', ['value-module'] = 'Wikidata/media', ['value-function'] = 'formatCommonsCategory', limit = 1, references = false, }, P374 = { datatype = 'external-id', }, P395 = { datatype = 'string', }, P407 = { datatype = 'wikibase-item', }, P410 = { datatype = 'wikibase-item', }, P412 = { datatype = 'wikibase-item', category = 'P910', }, P413 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'formatEntityWithGenderClaim', conjunction = ',&#32;', category = 'P910', }, P414 = { ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'applyDefaultTemplate', }, P421 = { datatype = 'wikibase-item', }, P473 = { datatype = 'string', }, P495 = { preset = 'country', }, P505 = { preset = 'list', }, P512 = { datatype = 'wikibase-item', ['property-module'] = 'Wikidata/P512', ['property-function'] = 'formatAcademicDegree', }, P527 = { preset = 'list', }, P528 = { references = false, qualifier = 'P972', }, P551 = { preset = 'place', }, P569 = { datatype = 'time', ['claim-module'] = 'Wikidata/date', ['claim-function'] = 'formatDateOfBirthClaim', }, P570 = { datatype = 'time', ['claim-module'] = 'Wikidata/date', ['claim-function'] = 'formatDateOfDeathClaim', }, P571 = { datatype = 'time', }, P576 = { datatype = 'time', }, P598 = { datatype = 'wikibase-item', }, P607 = { datatype = 'wikibase-item', preset = 'list', }, P625 = { datatype = 'globe-coordinate', }, P669 = { qualifier = 'P670', }, P685 = { formatter = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=$1', }, P721 = { preset = 'link', }, P764 = { preset = 'link', }, P803 = { datatype = 'wikibase-item', }, P856 = { datatype = 'url', }, P881 = { novalue = 'нет', category = 'P910', }, P884 = { preset = 'link', }, P915 = { category = 'P1740', }, P957 = { preset = 'link', }, P972 = { preset = 'catonly', }, P1077 = { preset = 'link', }, P1082 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1098 = { preset = 'quantity (date)', unit = 'чел.', }, P1120 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1128 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1114 = { datatype = 'quantity', qualifier = 'P585', }, P1174 = { preset = 'quantity (date)', unit = 'чел.', }, P1195 = { ['value-module'] = 'Wikidata/Software', ['value-function'] = 'formatExtension', conjunction = ' или ', }, P1215 = { datatype = 'quantity', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatVisualMagnitude' }, P1246 = { preset = 'link', }, P1249 = { datatype = 'time', }, P1352 = { preset = 'quantity (date)', }, P1376 = { datatype = 'wikibase-item', }, P1402 = { preset = 'link', }, P1448 = { preset = 'name', }, P1458 = { datatype = 'quantity', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatColorIndex' }, P1464 = { datatype = 'wikibase-item', }, P1476 = { preset = 'name', }, P1477 = { preset = 'name', }, P1532 = { preset = 'country', rank = '[rank:normal, rank:preferred]', }, P1543 = { datatype = 'commonsMedia', }, P1559 = { preset = 'name', }, P1603 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1621 = { size = '300x300px', }, P1692 = { preset = 'link', }, P1705 = { preset = 'name', }, P1753 = { rowArticle = true, }, P1809 = { preset = 'list', }, P1846 = { datatype = 'commonsMedia', fixdouble = true, }, P2031 = { preset = 'from-to', to = 'P2032', within = 'P570', }, P2043 = { preset = 'quantity (date)', }, P2044 = { datatype = 'quantity', }, P2046 = { preset = 'quantity (date)', siConversion = false, }, P2047 = { siConversion = false, }, P2048 = { conjunction = '&#32;или&#32;', }, P2060 = { siConversion = false, }, P2097 = { siConversion = false, }, P2120 = { siConversion = false, }, P2137 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2139 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2146 = { siConversion = false, }, P2214 = { siConversion = false }, P2226 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2257 = { siConversion = false }, P2260 = { siConversion = false }, P2295 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2324 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.' }, P2403 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2425 = { alt = 'Изображение орденской планки', }, P2583 = { siConversion = false, }, P2597 = { preset = 'catonly', }, P2650 = { datatype = 'wikibase-item', }, P2789 = { preset = 'list', }, P2896 = { siConversion = false, }, P2910 = { size = '100x80px', }, P3083 = { formatter = 'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=$1', }, P3086 = { siConversion = false, }, P3362 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P4614 = { category = 'P1200', }, P5348 = { siConversion = false, }, P6257 = { ['value-module'] = 'Wikidata/number', ['value-function'] = 'formatRA', }, P6258 = { ['value-module'] = 'Wikidata/number', ['value-function'] = 'formatDMS', }, P6259 = { ['references'] = false, }, P7584 = { siConversion = false, }, P8010 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P8224 = { alt = 'Изображение молекулярной модели', }, }, categories = { ['links-to-entities-with-missing-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без подписи', ['links-to-entities-with-wikibase-error'] = 'Википедия:Страницы с ошибками скриптов, использующих Викиданные', ['links-to-entities-with-missing-local-language-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без русской подписи', ['media-contains-local-caption'] = 'Википедия:Локальная подпись у изображения из Викиданных', ['media-contains-markup'] = 'Википедия:Статьи с вики-разметкой в изображении карточки', ['media-contains-local-double'] = 'Википедия:Изображение в статье дублирует изображение в карточке', ['value-contains-table'] = 'Википедия:Статьи с табличной вставкой в карточке', }, errors = { ['property-param-not-provided'] = 'Не дан параметр свойства', ['entity-not-found'] = 'Сущность не найдена.', ['unknown-claim-type'] = 'Неизвестный тип заявления.', ['unknown-snak-type'] = 'Неизвестный тип снэка.', ['unknown-datavalue-type'] = 'Неизвестный тип значения данных.', ['unknown-entity-type'] = 'Неизвестный тип сущности.', ['unknown-property-module'] = 'Вы должны установить и property-module, и property-function.', ['unknown-claim-module'] = 'Вы должны установить и claim-module, и claim-function.', ['unknown-value-module'] = 'Вы должны установить и value-module, и value-function.', ['property-module-not-found'] = 'Модуль для отображения свойства не найден', ['property-function-not-found'] = 'Функция для отображения свойства не найдена', ['claim-module-not-found'] = 'Модуль для отображения утверждения не найден.', ['claim-function-not-found'] = 'Функция для отображения утверждения не найдена.', ['value-module-not-found'] = 'Модуль для отображения значения не найден.', ['value-function-not-found'] = 'Функция для отображения значения не найдена.', }, i18n = { somevalue = "''неизвестно''", novalue = '', -- Обстоятельства источника Q5727902 = 'около ', Q18122778 = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп.</span> ', Q30230067 = 'возможно ', Q52834024 = '<span style="border-bottom: 1px dotted; cursor: help;" title="менее чем">&lt;</span> ', Q54418095 = '<span style="border-bottom: 1px dotted; cursor: help;" title="более чем">&gt;</span> ', Q60070514 = 'примерно ', thousandPowers = {'', ' тыс.', ' млн', ' млрд', ' трлн'}, }, deprecatedSources = { Q355 = true, -- Facebook Q36578 = true, -- Gemeinsame Normdatei Q63056 = true, -- Find a Grave Q212256 = true, -- АиФ Q504063 = true, -- Discogs Q523660 = true, -- International Music Score Library Project by https://ru.wikipedia.org/?diff=107090748 Q1798125 = true, -- LIBRIS Q2621214 = true, -- Geni Q15222191 = true, -- BNF Q15241312 = true, -- Freebase Q19938912 = true, -- BNF Q21697707 = true, -- Хайазг Q25328680 = true, -- Prabook Q29861311 = true, -- SNAC Q86999151 = true, -- WeChangEd }, }; bd6091486f675bebf109cb52de53a162b05a5243 Шаблон:Подстраницы шаблона Карточка 10 70 150 2025-01-02T20:14:31Z wikipedia, ruwikipedia>Kaganer 0 * {{tnav|карточка/Викигид}} wikitext text/x-wiki {{Навигационная таблица |имя = Подстраницы шаблона Карточка |state = {{{state|}}} |класс_списков = hlist hlist-items-nowrap |заголовок = Подстраницы шаблона {{tnav|Карточка}} |tracking = <includeonly>no</includeonly> |группа1 = {{!}}вверху= |список1 = * {{tnav|карточка/название}} (заголовок без уточнения) * {{tnav|карточка/имя}} (заголовок в обратном порядке и без уточнения) |группа2 = {{!}}вверху2= |список2 = * {{tnav|карточка/оригинал названия}} (свойство [[d:P:P1705|P1705]]) * {{tnav|карточка/оригинал названия произведения}} (свойство [[d:P:P1476|P1476]]) * {{tnav|карточка/официальное название}} (свойство [[d:P:P1448|P1448]]) * {{tnav|карточка/оригинал имени}} (свойство [[d:P:P1559|P1559]]) |группа3 = Разное |список3 = * {{tnav|карточка/изображение}} * {{tnav|карточка/Изображение рядом}} * {{tnav|карточка/флаг и герб}} (свойства [[d:p:P41|P41]] и [[d:p:P94|P94]]) * {{tnav|карточка/медали}} (свойство [[d:p:P166|P166]]) * {{tnav|карточка/хронология}} (свойства [[d:p:P155|P155]] и [[d:p:P156|P156]]) * {{tnav|карточка/период}} (свойства [[d:p:P580|P580]] и [[d:p:P582|P582]]) * {{tnav|карточка/коды в каталогах}} (свойство [[d:p:P528|P528]]) * {{tnav|карточка/блок}} * {{tnav|карточка/блок с маркерами}} |группа4 = {{!}}внизу= |список4 = * {{tnav|карточка/Викигид}} * {{tnav|карточка/Викиданные}} * {{tnav|карточка/Викисклад}} (свойство [[d:P:P373|P373]]) * {{tnav|карточка/Викитека}} * {{tnav|карточка/Викиучебник}} * {{tnav|карточка/Викицитатник}} |класс_внизу = hlist |внизу = ; См. также : [[Википедия:Шаблоны-карточки]] : [[:Категория:Шаблоны:Для шаблонов-карточек]] }}<noinclude> [[Категория:Навигационные шаблоны:Для шаблонов]] </noinclude> 3fd4b54a761d9de6d7ddaac86889f4abf8478d95 Шаблон:Doc 10 53 116 2025-01-07T17:31:17Z wikipedia, ruwikipedia>Stjn 0 не проверять страницы в основном пространстве на существование wikitext text/x-wiki <includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}} {{#if: {{{1|}}} | {{#ifexist: {{#if: {{NAMESPACE:{{{1}}}}} | {{{1}}} | {{SUBJECTSPACE}}:{{{1}}} }} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{#ifexist: {{SUBJECTSPACE}}:{{{1}}} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{Документировать|{{{1}}}}} }} }} | {{#ifexist: {{SUBJECTPAGENAME}}/doc | {{{{SUBJECTPAGENAME}}/doc}} | {{Документировать|{{SUBJECTPAGENAME}}/doc}} }} }} {{doc/end}}</includeonly><noinclude> {{doc}} </noinclude> 7298506ab2882f16fe7a52e0e080b2780b237bb9 Шаблон:Скрытый блок/styles.css 10 44 98 2025-01-10T09:29:25Z wikipedia, ruwikipedia>Wikisaurus 0 [[Обсуждение шаблона:Скрытый блок#Убрать правило о размере шрифта в 95%]] text text/plain .ts-Скрытый_блок { margin: 0; overflow: hidden; border-collapse: collapse; box-sizing: border-box; } .ts-Скрытый_блок-title { text-align: center; font-weight: bold; line-height: 1.6em; min-height: 1.2em; } .ts-Скрытый_блок .mw-collapsible-content { overflow-x: auto; overflow-y: hidden; clear: both; } .ts-Скрытый_блок::before, .ts-Скрытый_блок .mw-collapsible-toggle { padding-top: .1em; width: 6em; font-weight: normal; font-size: calc(90% / 0.95); } .ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { float: right; text-align: right; } .ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { float: left; text-align: left; } .ts-Скрытый_блок-gray { padding: 2px; border: 1px solid var(--border-color-base, #a2a9b1); } .ts-Скрытый_блок-transparent { border: none; } .ts-Скрытый_блок-gray .ts-Скрытый_блок-title { background: var(--background-color-neutral, #eaecf0); padding: .1em 6em; padding-right: 0; } .ts-Скрытый_блок-transparent .ts-Скрытый_блок-title { background: transparent; padding: .1em 5.5em; padding-right: 0; } .ts-Скрытый_блок-gray .mw-collapsible-content { padding: .25em 1em; } .ts-Скрытый_блок-transparent .mw-collapsible-content { padding: .25em 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { padding-right: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { padding-right: 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { padding-left: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { padding-left: 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 1em; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 6.5em; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle { padding-right: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-rightTitle, .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 0; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle, .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle { padding-right: 0; } .ts-Скрытый_блок + .ts-Скрытый_блок, .ts-Скрытый_блок + link + .ts-Скрытый_блок { border-top-style: hidden; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ b04b4e8d09f2a95b9b1ca08e8c10ef52169ec7f1 Шаблон:Карточка/doc 10 72 154 2025-01-23T06:13:39Z wikipedia, ruwikipedia>Mikhail Ryazanov 0 пунктуация, стилевые правки wikitext text/x-wiki {{docpage}} {{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}} {{СИШ}} Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]]. == Параметры == === Служебные === ; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>. ; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да». ; from: Указывается элемент Викиданных, из которого берётся информация. === Основные === ; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи. ; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия. ; вверху3: Дополнительный текст, отображаемый вверху таблицы. ; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>. ; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется. ; изображение2: Дополнительное изображение. ; изображение3: Дополнительное изображение. ; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1. ; метка<sub>n</sub>: Используется для подписи текста ; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках. ; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в &#60;tr&#62;, таких как {{t|карточка/блок}}. ; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто. Для вариантов форматирования значений, см. документацию [[Модуль:WikidataSelectors]]. ; внизу ; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом). === Стили === ; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}} ; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code> ; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code> ; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code> ; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание ; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение ; стиль_подписи: Применяется к подписи изображения ; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code> ; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n ; стиль_меток: Применяется к меткам ; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n ; стиль_текста: Применяется к тексту ; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n ; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''. ; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам. == Возможности == === Сдвоенные ячейки === Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код: <pre><nowiki> |текст2 = {{{параметр|}}} |стиль_текста2 = text-align:left; </nowiki></pre> === Необязательные ячейки === Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом: <pre><nowiki> |метка5 = Население |текст5 = {{{население|}}} </nowiki></pre> Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена. === Необязательные заголовки === Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>: <pre><nowiki> |заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}} |метка6 = Содержимое |текст6 = {{{содержимое|}}} |метка7 = Размещение |текст7 = {{{размещение|}}} </nowiki></pre> Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN. {| |- |<pre><nowiki> |заголовок1 = {{{заголовок1|}}} |метка1 = {{{метка1|}}} |текст1 = {{{текст1|}}} </nowiki></pre> |} {| |- |<pre><nowiki> |заголовок1 = заголовок_текст |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- ! заголовок_текст |} |<pre><nowiki> |заголовок1 = |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- | метка_текст|| текст_текст |} |} === Оформление параметров === Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён: <pre><nowiki> |метка6 = Масса |текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}} </nowiki></pre> А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например: <pre><nowiki> |метка6 = Раса |текст6 = {{#switch:{{{раса|}}} |Европеоиды = [[Европеоидная раса|Европеоиды]] |Негроиды = [[Негроидная раса|Негроиды]] |Монголоиды = [[Монголоидная раса|Монголоиды]] |{{{раса|}}} }} </nowiki></pre> == Пустой шаблон == <pre> {{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = |вверху2 = |изображение = |заголовок1 = |метка2 = |текст2 = |викиданные2 = |метка3 = |текст3 = |викиданные3 = |метка4 = |текст4 = |викиданные4 = |метка5 = |текст5 = |викиданные5 = |метка6 = |текст6 = |викиданные6 = |метка7 = |текст7 = |викиданные7 = |метка8 = |текст8 = |викиданные8 = |метка9 = |текст9 = |викиданные9 = |метка10 = |текст10 = |викиданные10 = ... |меткаN = |текстN = |викиданныеN = |внизу = }}<noinclude> {{doc}} </noinclude></pre> {{скрытый|Заголовок=11—20|Содержание=<pre> |метка11 = |текст11 = |викиданные11 = |метка12 = |текст12 = |викиданные12 = |метка13 = |текст13 = |викиданные13 = |метка14 = |текст14 = |викиданные14 = |метка15 = |текст15 = |викиданные15 = |метка16 = |текст16 = |викиданные16 = |метка17 = |текст17 = |викиданные17 = |метка18 = |текст18 = |викиданные18 = |метка19 = |текст19 = |викиданные19 = |метка20 = |текст20 = |викиданные20 = </pre>}} {{скрытый||Заголовок=21—30|Содержание=<pre> |метка21 = |текст21 = |викиданные21 = |метка22 = |текст22 = |викиданные22 = |метка23 = |текст23 = |викиданные23 = |метка24 = |текст24 = |викиданные24 = |метка25 = |текст25 = |викиданные25 = |метка26 = |текст26 = |викиданные26 = |метка27 = |текст27 = |викиданные27 = |метка28 = |текст28 = |викиданные28 = |метка29 = |текст29 = |викиданные29 = |метка30 = |текст30 = |викиданные30 = </pre>}} {{скрытый||Заголовок=31—40|Содержание=<pre> |метка31 = |текст31 = |викиданные31 = |метка32 = |текст32 = |викиданные32 = |метка33 = |текст33 = |викиданные33 = |метка34 = |текст34 = |викиданные34 = |метка35 = |текст35 = |викиданные35 = |метка36 = |текст36 = |викиданные36 = |метка37 = |текст37 = |викиданные37 = |метка38 = |текст38 = |викиданные38 = |метка39 = |текст39 = |викиданные39 = |метка40 = |текст40 = |викиданные40 = </pre>}} {{скрытый||Заголовок=41—50|Содержание=<pre> |метка41 = |текст41 = |викиданные41 = |метка42 = |текст42 = |викиданные42 = |метка43 = |текст43 = |викиданные43 = |метка44 = |текст44 = |викиданные44 = |метка45 = |текст45 = |викиданные45 = |метка46 = |текст46 = |викиданные46 = |метка47 = |текст47 = |викиданные47 = |метка48 = |текст48 = |викиданные48 = |метка49 = |текст49 = |викиданные49 = |метка50 = |текст50 = |викиданные50 = </pre>}} {{скрытый||Заголовок=51—60|Содержание=<pre> |метка51 = |текст51 = |викиданные51 = |метка52 = |текст52 = |викиданные52 = |метка53 = |текст53 = |викиданные53 = |метка54 = |текст54 = |викиданные54 = |метка55 = |текст55 = |викиданные55 = |метка56 = |текст56 = |викиданные56 = |метка57 = |текст57 = |викиданные57 = |метка58 = |текст58 = |викиданные58 = |метка59 = |текст59 = |викиданные59 = |метка60 = |текст60 = |викиданные60 = </pre>}} == Примерный шаблон для карточки персоны == <pre>{{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = {{карточка/имя|{{{имя|}}}}} |вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}} |изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}} |метка1 = Имя при рождении |текст1 = {{{имя при рождении|}}} |викиданные1 = p1477 |метка2 = Дата рождения |текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}} |метка3 = Место рождения |текст3 = {{{место рождения|}}} |викиданные3 = p19 |метка4 = Дата смерти |текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}} |метка5 = Место смерти |текст5 = {{{место смерти|}}} |викиданные5 = p20 |метка6 = Гражданство |текст6 = {{{гражданство|}}} |викиданные6 = p27 |метка7 = Сценические имена / Прозвище |текст7 = {{{прозвище|}}} |викиданные7 = p1449 |заголовок8 = {{wikidata|p856|{{{сайт|}}}}} |внизу = {{карточка/Викисклад|{{{викисклад|}}}}} }}</pre> Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом: * <code>13.05.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]]; * <code>12.06.1801 (31.05)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]]; * <code>12.01.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]). == Отслеживающие категории, подставляемые шаблоном == {{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}} == См. также == * [[Википедия:Шаблоны-карточки]] * {{t|Универсальная карточка}} * {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке) * [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]] * [[Участник:Jack who built the house/alignTemplateParameters.js]] {{Подстраницы шаблона Карточка}} <includeonly> [[Категория:Шаблоны-карточки|*]] [[Категория:Шаблоны:Мета-шаблоны]] </includeonly> 29badbe2200149ba091573e4e4e11106d20e0688 Заглавная страница 0 1 1 2025-01-31T12:36:03Z MediaWiki default 1 Создать главную страницу wikitext text/x-wiki __NOTOC__ == Добро пожаловать в {{SITENAME}}! == Эта главная страница была создана автоматически и, похоже, ещё не заменена. === Для бюрократа(-ов) этой вики === Здравствуйте и добро пожаловать на вашу новую вики! Благодарим Вас за выбор Miraheze в качестве хостинга, и мы надеемся, что вы будете пользоваться нашими услугами. Вы можете сразу же начать работать над вашем вики-сайтов, как только пожелаете. Нужна помощь? Нет проблем! Мы поможем вам с вашей вики по мере необходимости. Для того, чтобы начать, мы добавили несколько ссылок о работе с MediaWiki: * [[mw:Special:MyLanguage/Help:Contents|Обсуждение руководства MediaWiki (например, навигация, редактирование, удаление страниц, блокирование пользователей)]] * [[meta:Special:MyLanguage/FAQ|ЧЗВ по Miraheze]] * [[meta:Special:MyLanguage/Request features|Запрос изменений настроек вашей вики.]] (Изменения расширений, оформления и логотипа/фавикона должны выполняться через [[Special:ManageWiki]] в вашей вики, см. [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] для получения дополнительной информации.) ==== Но, Miraheze, я всё ещё не понимаю X! ==== Что ж, это не проблема. Даже если что-то не описано в документации/ЧЗВ, мы всё равно будем рады помочь вам. Вы можете найти нас здесь: * [[meta:Special:MyLanguage/Help center|На нашем собственном Miraheze вики]] * На [[phorge:|Phorge]] * На нашем [https://miraheze.org/discord Discord-сервере] * На IRC в #miraheze в irc.libera.chat (irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze вебчат])) === Для посетителя этой вики === Здравствуйте, заглавная страница по умолчанию ещё не была заменена бюрократом(-ами) этой вики. Возможно, администрация этого сайта разрабатывает эту страницу, поэтому мы рекомендуем вам зайти чуть позже. da708791005da529f6c1fffe139a9b3660d023e2 Файл:Logo of Aldazipedia.png 6 2 2 2025-01-31T13:30:56Z Генерал Альдации 2 wikitext text/x-wiki d 3c363836cf4e16666669a25da280a1865c2d2874 Файл:Text Aldazipedia.png 6 3 3 2025-01-31T13:34:26Z Генерал Альдации 2 wikitext text/x-wiki g 54fd1711209fb1c0781092374132c66e79e2241b Заглавная страница 0 1 4 1 2025-01-31T14:13:35Z Генерал Альдации 2 wikitext text/x-wiki __NOTOC__ {| class="wikitable" |<center>[[Файл:Logo of Aldazipedia.png|безрамки|80x80пкс]] [[Файл:Text Aldazipedia.png|безрамки]]</center> |- |Добро пожаловать на Альдаципедию, википедию о микронации Альдация, которую может редактировать каждый. |- | === '''О нас''' === |- |'''[[Альдация]]''' (также '''Республика Альдация''') является суверенной микронацией на небольшой территории в Псковской области. Мы были образованы на закате января - 31 января 2025 года подписали [[Декларация об образовании Альдации|декларацию об образовании Альдации]]. Наша идеология - социал-демократия, наш генерал - [[Роман Берестнёв]]. <center><big>''[[Альдация будет свободной|Альдация будет свободной!]]''</big></center> |} 089275caee1ad57ee9712ddcce3db8a64b4dd6a2 5 4 2025-01-31T14:14:02Z Генерал Альдации 2 wikitext text/x-wiki __NOTOC__ <center> {| class="wikitable" |<center>[[Файл:Logo of Aldazipedia.png|безрамки|80x80пкс]] [[Файл:Text Aldazipedia.png|безрамки]]</center> |- |Добро пожаловать на Альдаципедию, википедию о микронации Альдация, которую может редактировать каждый. |- | === '''О нас''' === |- |'''[[Альдация]]''' (также '''Республика Альдация''') является суверенной микронацией на небольшой территории в Псковской области. Мы были образованы на закате января - 31 января 2025 года подписали [[Декларация об образовании Альдации|декларацию об образовании Альдации]]. Наша идеология - социал-демократия, наш генерал - [[Роман Берестнёв]]. <center><big>''[[Альдация будет свободной|Альдация будет свободной!]]''</big></center> |} 4f6d726798524c1f4c637e1334f0fa76c7e3e89b 6 5 2025-01-31T14:14:12Z Генерал Альдации 2 Защитил страницу [[Заглавная страница]] ([Редактирование=Разрешено только администраторам] (бессрочно) [Переименование=Разрешено только администраторам] (бессрочно)) wikitext text/x-wiki __NOTOC__ <center> {| class="wikitable" |<center>[[Файл:Logo of Aldazipedia.png|безрамки|80x80пкс]] [[Файл:Text Aldazipedia.png|безрамки]]</center> |- |Добро пожаловать на Альдаципедию, википедию о микронации Альдация, которую может редактировать каждый. |- | === '''О нас''' === |- |'''[[Альдация]]''' (также '''Республика Альдация''') является суверенной микронацией на небольшой территории в Псковской области. Мы были образованы на закате января - 31 января 2025 года подписали [[Декларация об образовании Альдации|декларацию об образовании Альдации]]. Наша идеология - социал-демократия, наш генерал - [[Роман Берестнёв]]. <center><big>''[[Альдация будет свободной|Альдация будет свободной!]]''</big></center> |} 4f6d726798524c1f4c637e1334f0fa76c7e3e89b Файл:Jumpwiki.gif 6 4 7 2025-01-31T14:15:18Z Генерал Альдации 2 wikitext text/x-wiki JUMP bb0d79b578ec75d9a062b029e5cfd1928a02dd5b MediaWiki:Common.css 8 5 8 2025-01-31T14:22:37Z Генерал Альдации 2 Новая страница: «#footer-poweredbyico { display: none; } » css text/css #footer-poweredbyico { display: none; } 6d7d79dea47a3e4f595e6f0cf30c879ccf587ea2 9 8 2025-01-31T14:25:08Z Генерал Альдации 2 css text/css #footer-poweredbyico { display: none; } .floatright { margin: 0 0 0,5em 0,5em; clear: right; float: right; } .floatleft { margin: 0 0,5em 0,5em 0; float: left; clear: left; } 36136a09351355fd752e6fe2c01a734939ae0698 14 9 2025-01-31T14:38:49Z Генерал Альдации 2 css text/css #footer-poweredbyico { display: none; } .infoboxer { margin: 0 0 0,5em 0,5em; clear: right; float: right; background: #F8F9FA; border: solid black 1px; } .heading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 20px; } .subheading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 26; } 1131c031351a4f7fa86ad1916c34b7e632a2ff7f 16 14 2025-01-31T14:40:17Z Генерал Альдации 2 css text/css #footer-poweredbyico { display: none; } .infoboxer { margin: 0 0 0,5em 0,5em; clear: right; float: right; background: #F8F9FA; border: solid black 1px; } .heading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 20px; margin-left: 5px; margin-right: 5px; } .subheading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 26; margin-left: 5px; margin-right: 5px; } 311af5f84aa644ecf5f9b7180aca077a53f6b4ed 17 16 2025-01-31T14:43:30Z Генерал Альдации 2 css text/css #footer-poweredbyico { display: none; } .infoboxer { margin: 0 0 0,5em 0,5em; clear: right; float: right; background: #F8F9FA; border: solid black 1px; } .heading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 20px; margin-left: 5px; margin-right: 5px; } .subheading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 26; margin-left: 5px; margin-right: 5px; } .label { font-weight: bold; text-align: left; } .txt { text-align: right; } 062ef97c369633e82329e72015d5bb6a201f4254 19 17 2025-01-31T14:47:03Z Генерал Альдации 2 css text/css #footer-poweredbyico { display: none; } .infoboxer { margin: 0 0 0,5em 0,5em; clear: right; float: right; background: #F8F9FA; border: solid black 1px; } .heading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 20px; margin-left: 5px; margin-right: 5px; } .subheading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 26; margin-left: 5px; margin-right: 5px; } .label { font-weight: bold; text-align: left; } .txt { text-align: right; } .label, .txt { float: left; width: 50%; } .txt { text-align: right; } 6f50946e107800d8a7306dc382055ca045b8c302 20 19 2025-01-31T14:48:09Z Генерал Альдации 2 css text/css #footer-poweredbyico { display: none; } .infoboxer { margin: 0 0 0,5em 0,5em; clear: right; float: right; background: #F8F9FA; border: solid black 1px; } .heading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 20px; margin-left: 5px; margin-right: 5px; } .subheading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 26; margin-left: 5px; margin-right: 5px; } .label { font-weight: bold; text-align: left; margin-left: 5px; margin-right: 5px; } .txt { text-align: right; margin-left: 5px; margin-right: 5px; } .label, .txt { float: left; width: 50%; } .txt { text-align: right; } b25d1d98ee8c41916b7dcb441fda285674add172 21 20 2025-01-31T14:49:48Z Генерал Альдации 2 Отмена версии [[Special:Diff/20|20]], сделанной [[Special:Contributions/Генерал Альдации|Генерал Альдации]] ([[User talk:Генерал Альдации|обсуждение]]) css text/css #footer-poweredbyico { display: none; } .infoboxer { margin: 0 0 0,5em 0,5em; clear: right; float: right; background: #F8F9FA; border: solid black 1px; } .heading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 20px; margin-left: 5px; margin-right: 5px; } .subheading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 26; margin-left: 5px; margin-right: 5px; } .label { font-weight: bold; text-align: left; } .txt { text-align: right; } .label, .txt { float: left; width: 50%; } .txt { text-align: right; } 6f50946e107800d8a7306dc382055ca045b8c302 22 21 2025-01-31T14:53:42Z Генерал Альдации 2 css text/css #footer-poweredbyico { display: none; } .infoboxer { margin: 0 0 0,5em 0,5em; clear: right; float: right; background: #F8F9FA; border: solid black 1px; } .heading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 20px; margin-left: 5px; margin-right: 5px; } .subheading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 26; margin-left: 5px; margin-right: 5px; } .label { font-weight: bold; text-align: left; } .txt { text-align: right; } .label, .txt { float: left; width: 50%; } .txt { text-align: right; } .imge { max-width: 290px; max-height: 220px; margin: auto; } 814c20fdc857da7c2f759b3d9cd8a5cfce16e04e 24 22 2025-01-31T15:00:28Z Генерал Альдации 2 css text/css #footer-poweredbyico { display: none; } .infoboxer { margin: 0 0 0,5em 0,5em; clear: right; float: right; background: #F8F9FA; border: solid black 1px; max-width: 600px; } .heading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 20px; margin-left: 5px; margin-right: 5px; } .subheading { font-weight: bold; text-align: center; background-color: #CFE3FF; font-size: 26; margin-left: 5px; margin-right: 5px; } .label { font-weight: bold; text-align: left; } .txt { text-align: right; } .label, .txt { float: left; width: 50%; } .txt { text-align: right; } .imge { max-width: 290px; max-height: 220px; margin: auto; } 62b8ee9c08b57ad2100a74f1f525b7e7a449231b Шаблон:Карточка 10 8 15 2025-01-31T14:39:19Z Генерал Альдации 2 Страница для того, чтобы брать из неё код для своего инфобокса wikitext text/x-wiki <div class="infoboxer"> <div class="heading"> Заголовок </div> <div class="subheading"> Подзаголовок </div> </div> d435773e1060972f6005a5b4127a085cbf5ff5ef 18 15 2025-01-31T14:45:02Z Генерал Альдации 2 wikitext text/x-wiki <div class="infoboxer"> <div class="heading"> Заголовок </div> <div class="subheading"> Подзаголовок</div> <div class="label"> ТНР </div> <div class="txt"> Танну-Тува </div> </div> de2dac2b0de79e3bf0e3af90c31514029508ebee 23 18 2025-01-31T14:55:09Z Генерал Альдации 2 wikitext text/x-wiki <div class="infoboxer"> <div class="heading"> Заголовок </div> <div class="imge"> [[Файл:Usovo-houses.jpg|мини|без]] </div> <div class="subheading"> Подзаголовок</div> <div class="label"> ТНР </div> <div class="txt"> Танну-Тува </div> </div> 4ea1b5efbbf67793758c6577ffbe33c97442c351 25 23 2025-01-31T15:00:45Z Генерал Альдации 2 wikitext text/x-wiki <div class="infoboxer"> <div class="heading"> Заголовок </div> <div class="imge"><center> [[Файл:Usovo-houses.jpg|мини|без|290px|220px|СССР]] </div> <div class="subheading"> Подзаголовок </center></div> <div class="label"> ТНР </div> <div class="txt"> Танну-Тува </div> <div class="label"> ДНР </div> <div class="txt"> Донецкая Народная Республика </div> <div class="label"> А ещё </div> <div class="txt"> Я пират </div> </div> cbaee7fd48623fae8c522a3a86afe5d1a119154c 27 25 2025-01-31T15:23:56Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <div class="infoboxer"> <div class="heading"> Заголовок </div> <div class="imge"><center> [[Файл:Usovo-houses.jpg|мини|без|290px|220px|СССР]] </div> <div class="subheading"> Подзаголовок </center></div> <div class="label"> ТНР </div> <div class="txt"> Танну-Тува </div> <div class="label"> ДНР </div> <div class="txt"> Донецкая Народная Республика </div> <div class="label"> А ещё </div> <div class="txt"> Я пират </div> </div> cbaee7fd48623fae8c522a3a86afe5d1a119154c Модуль:Arguments 828 10 31 30 2025-01-31T15:23:57Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val == '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) == 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) == 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end local function matchesTitle(given, title) local tp = type( given ) return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title end local translate_mt = { __index = function(t, k) return k end } function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} --[[ -- Set up argument translation. --]] options.translate = options.translate or {} if getmetatable(options.translate) == nil then setmetatable(options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} for k,v in pairs(options.translate) do options.backtranslate[v] = k end end if options.backtranslate and getmetatable(options.backtranslate) == nil then setmetatable(options.backtranslate, { __index = function(t, k) if options.translate[k] ~= k then return nil else return k end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] local fargs, pargs, luaArgs if type(frame.args) == 'table' and type(frame.getParent) == 'function' then if options.wrappers then --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] local parent = frame:getParent() if not parent then fargs = frame.args else local title = parent:getTitle():gsub('/песочница$', '') local found = false if matchesTitle(options.wrappers, title) then found = true elseif type(options.wrappers) == 'table' then for _,v in pairs(options.wrappers) do if matchesTitle(v, title) then found = true break end end end -- We test for false specifically here so that nil (the default) acts like true. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else -- options.wrapper isn't set, so check the other options. if not options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame:getParent() pargs = parent and parent.args or nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. local argTables = {fargs} argTables[#argTables + 1] = pargs argTables[#argTables + 1] = luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error( "bad value assigned to option 'valueFunc'" .. '(function expected, got ' .. type(tidyVal) .. ')', 2 ) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable(args, metatable) local function mergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for _, t in ipairs(tables) do for key, val in pairs(t) do if metaArgs[key] == nil and nilArgs[key] ~= 'h' then local tidiedVal = tidyVal(key, val) if tidiedVal == nil then nilArgs[key] = 's' else metaArgs[key] = tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index = function (t, key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] if type(key) == 'string' then key = options.translate[key] end local val = metaArgs[key] if val ~= nil then return val elseif metatable.donePairs or nilArgs[key] then return nil end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTable[key]) if argTableVal ~= nil then metaArgs[key] = argTableVal return argTableVal end end nilArgs[key] = 'h' return nil end metatable.__newindex = function (t, key, val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. if type(key) == 'string' then key = options.translate[key] end if options.readOnly then error( 'could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2 ) elseif options.noOverwrite and args[key] ~= nil then error( 'could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2 ) elseif val == nil then --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key] = nil nilArgs[key] = 'h' else metaArgs[key] = val end end local function translatenext(invariant) local k, v = next(invariant.t, invariant.k) invariant.k = k if k == nil then return nil elseif type(k) ~= 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate[k] if backtranslate == nil then -- Skip this one. This is a tail call, so this won't cause stack overflow return translatenext(invariant) else return backtranslate, v end end end metatable.__pairs = function () -- Called when pairs is run on the args table. if not metatable.donePairs then mergeArgs(argTables) metatable.donePairs = true end return translatenext, { t = metaArgs } end local function inext(t, i) -- This uses our __index metamethod local v = t[i + 1] if v ~= nil then return i + 1, v end end metatable.__ipairs = function (t) -- Called when ipairs is run on the args table. return inext, t, 0 end return args end return arguments e6be8dfccffa2057c3d50700f350d8d140c1dbf9 Модуль:TableTools 828 11 33 32 2025-01-31T15:23:57Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain --[[ ------------------------------------------------------------------------------------ -- TableTools -- -- -- -- This module includes a number of functions for dealing with Lua tables. -- -- It is a meta-module, meant to be called from other Lua modules, and should -- -- not be called directly from #invoke. -- ------------------------------------------------------------------------------------ --]] local libraryUtil = require('libraryUtil') local p = {} -- Define often-used variables and functions. local floor = math.floor local infinity = math.huge local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti --[[ ------------------------------------------------------------------------------------ -- isPositiveInteger -- -- This function returns true if the given value is a positive integer, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a given table key is in the array part or the -- hash part of a table. ------------------------------------------------------------------------------------ --]] function p.isPositiveInteger(v) if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- isNan -- -- This function returns true if the given number is a NaN value, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a value can be a valid table key. Lua will -- generate an error if a NaN is used as a table key. ------------------------------------------------------------------------------------ --]] function p.isNan(v) if type(v) == 'number' and tostring(v) == '-nan' then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- shallowClone -- -- This returns a clone of a table. The value returned is a new table, but all -- subtables and functions are shared. Metamethods are respected, but the returned -- table will have no metatable of its own. ------------------------------------------------------------------------------------ --]] function p.shallowClone(t) local ret = {} for k, v in pairs(t) do ret[k] = v end return ret end --[[ ------------------------------------------------------------------------------------ -- removeDuplicates -- -- This removes duplicate values from an array. Non-positive-integer keys are -- ignored. The earliest value is kept, and all subsequent duplicate values are -- removed, but otherwise the array order is unchanged. ------------------------------------------------------------------------------------ --]] function p.removeDuplicates(t) checkType('removeDuplicates', 1, t, 'table') local isNan = p.isNan local ret, exists = {}, {} for i, v in ipairs(t) do if isNan(v) then -- NaNs can't be table keys, and they are also unique, so we don't need to check existence. ret[#ret + 1] = v else if not exists[v] then ret[#ret + 1] = v exists[v] = true end end end return ret end --[[ ------------------------------------------------------------------------------------ -- numKeys -- -- This takes a table and returns an array containing the numbers of any numerical -- keys that have non-nil values, sorted in numerical order. ------------------------------------------------------------------------------------ --]] function p.numKeys(t) checkType('numKeys', 1, t, 'table') local isPositiveInteger = p.isPositiveInteger local nums = {} for k, v in pairs(t) do if isPositiveInteger(k) then nums[#nums + 1] = k end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- affixNums -- -- This takes a table and returns an array containing the numbers of keys with the -- specified prefix and suffix. For example, for the table -- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will -- return {1, 3, 6}. ------------------------------------------------------------------------------------ --]] function p.affixNums(t, prefix, suffix) checkType('affixNums', 1, t, 'table') checkType('affixNums', 2, prefix, 'string', true) checkType('affixNums', 3, suffix, 'string', true) local function cleanPattern(s) -- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally. s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1') return s end prefix = prefix or '' suffix = suffix or '' prefix = cleanPattern(prefix) suffix = cleanPattern(suffix) local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$' local nums = {} for k, v in pairs(t) do if type(k) == 'string' then local num = mw.ustring.match(k, pattern) if num then nums[#nums + 1] = tonumber(num) end end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- numData -- -- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table -- of subtables in the format -- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} } -- Keys that don't end with an integer are stored in a subtable named "other". -- The compress option compresses the table so that it can be iterated over with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.numData(t, compress) checkType('numData', 1, t, 'table') checkType('numData', 2, compress, 'boolean', true) local ret = {} for k, v in pairs(t) do local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$') if num then num = tonumber(num) local subtable = ret[num] or {} if prefix == '' then -- Positional parameters match the blank string; put them at the start of the subtable instead. prefix = 1 end subtable[prefix] = v ret[num] = subtable else local subtable = ret.other or {} subtable[k] = v ret.other = subtable end end if compress then local other = ret.other ret = p.compressSparseArray(ret) ret.other = other end return ret end --[[ ------------------------------------------------------------------------------------ -- compressSparseArray -- -- This takes an array with one or more nil values, and removes the nil values -- while preserving the order, so that the array can be safely traversed with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.compressSparseArray(t) checkType('compressSparseArray', 1, t, 'table') local ret = {} local nums = p.numKeys(t) for _, num in ipairs(nums) do ret[#ret + 1] = t[num] end return ret end --[[ ------------------------------------------------------------------------------------ -- sparseIpairs -- -- This is an iterator for sparse arrays. It can be used like ipairs, but can -- handle nil values. ------------------------------------------------------------------------------------ --]] function p.sparseIpairs(t) checkType('sparseIpairs', 1, t, 'table') local nums = p.numKeys(t) local i = 0 local lim = #nums return function () i = i + 1 if i <= lim then local key = nums[i] return key, t[key] else return nil, nil end end end --[[ ------------------------------------------------------------------------------------ -- size -- -- This returns the size of a key/value pair table. It will also work on arrays, -- but for arrays it is more efficient to use the # operator. ------------------------------------------------------------------------------------ --]] function p.size(t) checkType('size', 1, t, 'table') local i = 0 for k in pairs(t) do i = i + 1 end return i end local function defaultKeySort(item1, item2) -- "number" < "string", so numbers will be sorted before strings. local type1, type2 = type(item1), type(item2) if type1 ~= type2 then return type1 < type2 else -- This will fail with table, boolean, function. return item1 < item2 end end --[[ Returns a list of the keys in a table, sorted using either a default comparison function or a custom keySort function. ]] function p.keysToList(t, keySort, checked) if not checked then checkType('keysToList', 1, t, 'table') checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' }) end local list = {} local index = 1 for key, value in pairs(t) do list[index] = key index = index + 1 end if keySort ~= false then keySort = type(keySort) == 'function' and keySort or defaultKeySort table.sort(list, keySort) end return list end --[[ Iterates through a table, with the keys sorted using the keysToList function. If there are only numerical keys, sparseIpairs is probably more efficient. ]] function p.sortedPairs(t, keySort) checkType('sortedPairs', 1, t, 'table') checkType('sortedPairs', 2, keySort, 'function', true) local list = p.keysToList(t, keySort, true) local i = 0 return function() i = i + 1 local key = list[i] if key ~= nil then return key, t[key] else return nil, nil end end end --[[ Returns true if all keys in the table are consecutive integers starting at 1. --]] function p.isArray(t) checkType("isArray", 1, t, "table") local i = 0 for k, v in pairs(t) do i = i + 1 if t[i] == nil then return false end end return true end -- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 } function p.invert(array) checkType("invert", 1, array, "table") local map = {} for i, v in ipairs(array) do map[v] = i end return map end --[[ { "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true } --]] function p.listToSet(t) checkType("listToSet", 1, t, "table") local set = {} for _, item in ipairs(t) do set[item] = true end return set end --[[ Recursive deep copy function. Preserves identities of subtables. ]] local function _deepCopy(orig, includeMetatable, already_seen) -- Stores copies of tables indexed by the original table. already_seen = already_seen or {} local copy = already_seen[orig] if copy ~= nil then return copy end if type(orig) == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen) end already_seen[orig] = copy if includeMetatable then local mt = getmetatable(orig) if mt ~= nil then local mt_copy = deepcopy(mt, includeMetatable, already_seen) setmetatable(copy, mt_copy) already_seen[mt] = mt_copy end end else -- number, string, boolean, etc copy = orig end return copy end function p.deepCopy(orig, noMetatable, already_seen) checkType("deepCopy", 3, already_seen, "table", true) return _deepCopy(orig, not noMetatable, already_seen) end --[[ Concatenates all values in the table that are indexed by a number, in order. sparseConcat{ a, nil, c, d } => "acd" sparseConcat{ nil, b, c, d } => "bcd" ]] function p.sparseConcat(t, sep, i, j) local list = {} local list_i = 0 for _, v in p.sparseIpairs(t) do list_i = list_i + 1 list[list_i] = v end return table.concat(list, sep, i, j) end --[[ -- This returns the length of a table, or the first integer key n counting from -- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return -- a different value when there are gaps in the array portion of the table. -- Intended to be used on data loaded with mw.loadData. For other tables, use #. -- Note: #frame.args in frame object always be set to 0, regardless of -- the number of unnamed template parameters, so use this function for -- frame.args. --]] function p.length(t) local i = 1 while t[i] ~= nil do i = i + 1 end return i - 1 end function p.inArray(arr, valueToFind) checkType("inArray", 1, arr, "table") -- if valueToFind is nil, error? for _, v in ipairs(arr) do if v == valueToFind then return true end end return false end return p fe918509f168332267834b3a6f5c219a9de5b2e7 Модуль:Template call code 828 12 35 34 2025-01-31T15:23:58Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local ru = mw.language.new('ru') local p = {} -- Используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k, v in pairs(other) do res[k] = v end return res end local function makeInvokeFunc(funcName, flags) return function (frame) local args = copy(getArgs(frame, { trim = false, removeBlanks = false })) return p[funcName](args, flags) end end --предотвращает обработку вики-текста в отображении образца local function processText(str, nowiki) local res = str if nowiki then str = mw.text.unstripNoWiki(str) str = string.gsub(str, '%[', '&#91;') str = string.gsub(str, '%]', '&#93;') str = string.gsub(str, '<', '&lt;') str = string.gsub(str, '>', '&gt;') str = string.gsub(str, '{', '&#123;') str = string.gsub(str, '|', '&#124;') str = string.gsub(str, '}', '&#125;') str = string.gsub(str, '\'', '&#39;') str = string.gsub(str, '"', '&quot;') str = string.gsub(str, '(://)', '<span>%1</span>') end return str end local function addParams(args, params) local text, equals_pos, param, value = '', 0, '', '' local function addPipe() if params.spaced then text = text .. ' ' end text = text .. '<span class="' if not params.spaced then text = text .. ' ts-templateCallCode-pipe' end if not params.black then text = text .. ' ts-templateCallCode-weak' end -- &#124;, чтобы не трактовалось как разделитель ячеек в таблицах text = text .. '">&#124;</span>' end local beforeParam = '<span class="ts-templateCallCode-param">' local afterParam = '</span>' for k, v in pairs(args) do if type(k) == 'number' then -- Неименованные параметры if k >= params.from then equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos - 2 then equals_pos = nil end if equals_pos then -- Содержащие «=» преобразуем в именованные param = v:sub(1, equals_pos - 1) value = v:sub(equals_pos + 1) addPipe() text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam else -- Истинно неименованные addPipe() local paramValue = processText(v, params.nowiki) if #paramValue ~= 0 then text = text .. beforeParam .. paramValue .. afterParam end end end elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида addPipe() text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam end end return text end function p._main(args, flags) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local optpText if not flags.withoutParams then if name then local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp if spanOffset then optpText = mw.ustring.sub(name, spanOffset) name = mw.ustring.sub(name, 1, spanOffset - 1) end end end local yesno = require('Module:Yesno') local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr local tag, style, comment, lang, sister, global, textInPlaceOfName, namePrefix, prefix, postfix, nowiki local spaced, from if flags.withoutParams then for i, v in ipairs(args) do if v == 'nl' or v == 'nolink' then noLink = true elseif v == 's' then subst = true elseif v == 'п' then podst = true elseif v == 'g' then global = true elseif v == 'nav' then nav = true elseif v == 'noredir' then noRedirect = true elseif v == 'u' then ucFirst = true elseif v == 'b' then black = true elseif v == 'nobr' then nobr = true end end tag = args.tag or 'span' style = args.style comment = args.comment lang = args.lang sister = args.sister textInPlaceOfName = args.text namePrefix = args.nameprefix prefix = args.prefix postfix = args.postfix nowiki = args.nowiki else noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) subst = yesno(args._s, false) podst = yesno(args['_п'], false) global = yesno(args._g, false) nav = yesno(args._nav, false) noRedirect = yesno(args._noredir, false) ucFirst = yesno(args._u, false) black = yesno(args._b, false) nobr = yesno(args._nobr, false) tag = args._tag or 'span' style = args._style comment = args._comment lang = args._lang sister = args._sister textInPlaceOfName = args._text namePrefix = args._nameprefix prefix = args._prefix postfix = args._postfix nowiki = args._nowiki spaced = yesno(args._spaced, false) from = (tonumber(args._from) or 2) - 1 end global = global or name and mw.ustring.sub(name, 1, 1) == ':' black = black or tag ~= 'span' if textInPlaceOfName == '' then textInPlaceOfName = nil end if comment == '' then comment = nil end if lang == '' then lang = nil end if sister == '' then sister = nil end if namePrefix == '' then namePrefix = nil end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then podst = true name = mw.ustring.sub(trimmedName, 7) end end if subst then namePrefix = 'subst:' elseif podst then namePrefix = 'подст:' end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not ucFirst and ( ( ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if lang then table.insert(prefixes, lang) end if sister then table.insert(prefixes, sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = noLink or currentTitle == titleObject if not noLink then if not noRedirect or ( noRedirect and not lang and not sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if tag then text = text .. '<' .. tag .. ' class="ts-templateCallCode' if nobr then text = text .. ' nowrap' end text = text .. '"' if style then text = text .. ' style="' .. style .. '"' end text = text .. '>' end if prefix then text = text .. processText(prefix, nowiki) end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-opening' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">{{' if namePrefix then text = text .. namePrefix end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">' local commentedLabel if comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}}) commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (textInPlaceOfName or name) .. '</span>' end local label = (commentedLabel or textInPlaceOfName or name) if not noLink then if noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd if noRedirect then text = text .. '</span>' end else text = text .. label end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end if not flags.withoutParams then if optpText then text = text .. optpText end text = text .. addParams(args, { spaced = spaced, black = black, nowiki = nowiki, from = from }) if spaced then text = text .. ' ' end end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-closing' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">}}</span>' if postfix then text = text .. processText(postfix, nowiki) end if tag then text = text .. '</' .. tag .. '>' end local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } } return ts .. text end function p._onlyParams(args) local yesno = require('Module:Yesno') return addParams(args, { spaced = yesno(args._spaced, false), black = true, nowiki = yesno(args._nowiki, false), from = 1 }) end p.withoutParams = makeInvokeFunc('_main', {withoutParams = true}) p.withParams = makeInvokeFunc('_main', {withoutParams = false}) p.onlyParams = makeInvokeFunc('_onlyParams') return p c4cde66869b509219e9bf629a766ce30ad0bdf97 Модуль:Yesno 828 13 37 36 2025-01-31T15:23:58Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val == 'true' or val == 't' or val == 'да' or val == 'д' -- кириллица or val == 'у' or val == '+' or tonumber(val) == 1 then return true elseif val == false or val == 'no' or val == 'n' or val == 'false' or val == 'f' or val == 'нет' or val == 'н' or val == '-' or tonumber(val) == 0 then return false else return default end end ae94e12a838e770797317ed07b57b330ffeb7658 Модуль:Template call code/styles.css 828 14 39 38 2025-01-31T15:23:58Z Генерал Альдации 2 1 версия импортирована text text/plain .ts-templateCallCode-weak { color: #72777d; } .ts-templateCallCode-pipe { margin: 0 2px; } .ts-templateCallCode-pipe + .ts-templateCallCode-pipe, /* Template:Optp */ .ts-templateCallCode-pipe + .ts-templateCallCode-param > .ts-templateCallCode-weak:first-child > .ts-templateCallCode-pipe:first-child { margin-left: 0; } .ts-templateCallCode-param + .ts-templateCallCode-closing { margin-left: 2px; } span.ts-templateCallCode > .ts-templateCallCode-templateName a { /* Решение из https://ru.wikipedia.org/wiki/Шаблон:Фиттс */ padding: 0 0.5em !important; /* Перезаписываем стиль для .plainlinks a.external */ position: relative; margin: -0.5em; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ b3ed166240cf28c48a58b8d992794b753b2c6ef5 Модуль:Message box 828 15 41 40 2025-01-31T15:23:58Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('strict') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLanguage() -- Define constants local CONFIG_MODULE = 'Module:Message box/configuration' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Категория:%s|%s]]', cat, sort) else cat = string.format('[[Категория:%s]]', cat) end self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id self.name = args.name if self.name then self:addClass('mbox-' .. string.gsub(self.name,' ','_')) end if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs self.dataLabel1 = args['data-label-1'] self.dataLabel2 = args['data-label-2'] self.dataLabel3 = args['data-label-3'] self.dataValue1 = args['data-value-1'] self.dataValue2 = args['data-value-2'] self.dataValue3 = args['data-value-3'] -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then self.name = args.name if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName) self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else if args.sect and args.sect ~= '' or nil then local issue_sect = args.issue_sect issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil local text_sect = args.text_sect text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil local issues = {} table.insert(issues, issue_sect) table.insert(issues, text_sect) self.issue = table.concat(issues, ' ') else local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText = 'Соответствующую дискуссию можно найти на' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s [[%s#%s|странице обсуждения]].', talkText, talkTitle.prefixedText, talk ) end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then local status, result = pcall(formatDate, args.date) if status then date = string.format("(<span class='date'>%s</span>)", result) else date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date) end elseif args.date == '' and self.isTemplatePage then date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет end if date then self.date = string.format(" <span class='mbox-date'>''%s''</span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end if args.shortFix then self.shortFix = args.shortFix end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text self.textsmall = args['text-small'] end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell if cfg.imageEmptyCellStyle then self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' end -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= '' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or cfg.imageSize or '40x40px' self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end -- set templatestyles self.base_templatestyles = cfg.templatestyles end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg local date = nil if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local status, result = pcall(formatDate, args.date, 'xg Y') if status then date = result end date = type(date) == 'string' and date local preposition = 'с' local suffix = 'года' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix) self:addCat(0, catTitle) catTitle = getTitleObject('Категория:' .. catTitle) local status, result = pcall(formatDate, args.date) if not status then self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort) end if self.isSubstituted then self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами') end if self.isSmall then self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return categoryHandler{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end -- Conditional TemplateStyles loading if self.base_templatestyles then local frame = mw.getCurrentFrame() root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.base_templatestyles }, }) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.dataLabel1 then boxTable:attr('data-' .. self.dataLabel1, self.dataValue1) end if self.dataLabel2 then boxTable:attr('data-' .. self.dataLabel2, self.dataValue2) end if self.dataLabel3 then boxTable:attr('data-' .. self.dataLabel3, self.dataValue3) end if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):css('width', '52px') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') :cssText(self.imageEmptyCellStyle or nil) end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-div') :wikitext(self.issue or nil) local textsmallCellDiv = textCell:tag('div') textsmallCellDiv :addClass('mbox-textsmall-div hide-when-compact') :cssText(self.textsmallstyle) :wikitext(self.textsmall or nil) if (self.talk or self.fix) and not self.isSmall then textsmallCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.fix and (' ' .. self.fix) or nil) :wikitext(self.talk and (' ' .. self.talk) or nil) end if self.textsmall or self.fix or self.talk then textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil) else textCellDiv:wikitext(self.date and (' ' .. self.date) or nil) end if self.info and not self.isSmall then textsmallCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textsmallCellDiv:tag('small') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end if self.shortFix then textCell:tag('div') :addClass('mbox-multiply') :tag('span') :wikitext(string.format("%s", self.shortFix)) :tag('span') :wikitext(self.date and (' ' .. self.date) or nil) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):css('width', '52px') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :css('text-align', 'center') :wikitext(string.format( 'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f2539b657a9cdadde7c0dd5ad270d3095b2bdd54 Модуль:Category handler 828 16 43 42 2025-01-31T15:23:59Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all namespace aliases -- -- are supported, and namespace names are detected automatically for -- -- the local wiki. This module requires [[Module:Namespace detect]] -- -- and [[Module:Yesno]] to be available on the local wiki. It can be -- -- configured for different wikis by altering the values in -- -- [[Module:Category handler/config]], and pages can be blacklisted -- -- from categorisation by using [[Module:Category handler/blacklist]]. -- -- -- -------------------------------------------------------------------------------- -- Load required modules local yesno = require('Module:Yesno') -- Lazily load things we don't always need local mShared, mappings local p = {} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function trimWhitespace(s, removeBlanks) if type(s) ~= 'string' then return s end s = s:match('^%s*(.-)%s*$') if removeBlanks then if s ~= '' then return s else return nil end else return s end end -------------------------------------------------------------------------------- -- CategoryHandler class -------------------------------------------------------------------------------- local CategoryHandler = {} CategoryHandler.__index = CategoryHandler function CategoryHandler.new(data, args) local obj = setmetatable({ _data = data, _args = args }, CategoryHandler) -- Set the title object do local pagename = obj:parameter('demopage') local success, titleObj if pagename then success, titleObj = pcall(mw.title.new, pagename) end if success and titleObj then obj.title = titleObj if titleObj == mw.title.getCurrentTitle() then obj._usesCurrentTitle = true end else obj.title = mw.title.getCurrentTitle() obj._usesCurrentTitle = true end end -- Set suppression parameter values for _, key in ipairs{'nocat', 'categories'} do local value = obj:parameter(key) value = trimWhitespace(value, true) obj['_' .. key] = yesno(value) end do local subpage = obj:parameter('subpage') local category2 = obj:parameter('category2') if type(subpage) == 'string' then subpage = mw.ustring.lower(subpage) end if type(category2) == 'string' then subpage = mw.ustring.lower(category2) end obj._subpage = trimWhitespace(subpage, true) obj._category2 = trimWhitespace(category2) -- don't remove blank values end return obj end function CategoryHandler:parameter(key) local parameterNames = self._data.parameters[key] local pntype = type(parameterNames) if pntype == 'string' or pntype == 'number' then return self._args[parameterNames] elseif pntype == 'table' then for _, name in ipairs(parameterNames) do local value = self._args[name] if value ~= nil then return value end end return nil else error(string.format( 'invalid config key "%s"', tostring(key) ), 2) end end function CategoryHandler:isSuppressedByArguments() return -- See if a category suppression argument has been set. self._nocat == true or self._categories == false or ( self._category2 and self._category2 ~= self._data.category2Yes and self._category2 ~= self._data.category2Negative ) -- Check whether we are on a subpage, and see if categories are -- suppressed based on our subpage status. or self._subpage == self._data.subpageNo and self.title.isSubpage or self._subpage == self._data.subpageOnly and not self.title.isSubpage end function CategoryHandler:shouldSkipBlacklistCheck() -- Check whether the category suppression arguments indicate we -- should skip the blacklist check. return self._nocat == false or self._categories == true or self._category2 == self._data.category2Yes end function CategoryHandler:matchesBlacklist() if self._usesCurrentTitle then return self._data.currentTitleMatchesBlacklist else mShared = mShared or require('Module:Category handler/shared') return mShared.matchesBlacklist( self.title.prefixedText, mw.loadData('Module:Category handler/blacklist') ) end end function CategoryHandler:isSuppressed() -- Find if categories are suppressed by either the arguments or by -- matching the blacklist. return self:isSuppressedByArguments() or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist() end function CategoryHandler:getNamespaceParameters() if self._usesCurrentTitle then return self._data.currentTitleNamespaceParameters else if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end return mShared.getNamespaceParameters( self.title, mappings ) end end function CategoryHandler:namespaceParametersExist() -- Find whether any namespace parameters have been specified. -- We use the order "all" --> namespace params --> "other" as this is what -- the old template did. if self:parameter('all') then return true end if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end for ns, params in pairs(mappings) do for i, param in ipairs(params) do if self._args[param] then return true end end end if self:parameter('other') then return true end return false end function CategoryHandler:getCategories() local params = self:getNamespaceParameters() local nsCategory for i, param in ipairs(params) do local value = self._args[param] if value ~= nil then nsCategory = value break end end if nsCategory ~= nil or self:namespaceParametersExist() then -- Namespace parameters exist - advanced usage. if nsCategory == nil then nsCategory = self:parameter('other') end local ret = {self:parameter('all')} local numParam = tonumber(nsCategory) if numParam and numParam >= 1 and math.floor(numParam) == numParam then -- nsCategory is an integer ret[#ret + 1] = self._args[numParam] else ret[#ret + 1] = nsCategory end if #ret < 1 then return nil else return table.concat(ret) end elseif self._data.defaultNamespaces[self.title.namespace] then -- Namespace parameters don't exist, simple usage. return self._args[1] end return nil end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- Used for testing purposes. return { CategoryHandler = CategoryHandler } end function p._main(args, data) data = data or mw.loadData('Module:Category handler/data') local handler = CategoryHandler.new(data, args) if handler:isSuppressed() then return nil end return handler:getCategories() end function p.main(frame, data) data = data or mw.loadData('Module:Category handler/data') local args = require('Module:Arguments').getArgs(frame, { wrappers = data.wrappers, valueFunc = function (k, v) v = trimWhitespace(v) if type(k) == 'number' then if v ~= '' then return v else return nil end else return v end end }) return p._main(args, data) end return p b74dd63857b24904ac452429b11213f18647471f Модуль:Calendar 828 17 45 44 2025-01-31T15:23:59Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local p = {} -- Необходимые модули и переменные local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local mwlang = mw.getContentLanguage() local err = "―" -- NthDay nil result local tCon = table.concat -- 00) Блок многократно используемых списков local bool_to_number={ [true]=1, [false]=0 } local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"} local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6, ["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""} local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local params = { {"г", "g"}, {"ю", "j"}} local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'} -- duplicates: -- AST, BST, CST, ECT, IST, MST, PST, SST, local known_tzs = { ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00', AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00', AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00', AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00', BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00', BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30', CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45', CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00', COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00', CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00', ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00', EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00', GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00', GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00', HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30', IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00', LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30', MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30', MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30', NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00', PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00', SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00', SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00', UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00', WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00', -- US Millitary (for RFC-822) Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00', } local category = { ["no_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->", ["incomplete_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->", ["without_verification"]= "<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->", ["erroneous_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->" } -- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением local e = { ["start"]="<span class=error>Ошибка: ", ["ending"]=".</span>", ["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами", ["no_valid_date"]="дата «%s» не является корректной", ["wrong_jd"]="юлианская дата %s вне диапазона", ["no_data"]="нет входящих данных", ["too_many_arguments"]="ожидается менее %i аргументов", ["too_little_arguments"]="ожидается более %i аргументов", ["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница", ["unknown_param"]="параметр %s неизвестен", ["unknown_error"]="неизвестная ошибка", ["tech_error"]="ошибка в функции %s", ["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД" -- [""]="", } local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST", "AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT", "BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST", "CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT", "CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT", "FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST", "HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST", "LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT", "NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT", "SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET", "VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"} local pattern = { -- для распознавания дат, переданных одним строчным параметром {"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd {"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy {"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy {"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm {"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y {"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y {"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y } local time_units = {"year","month","day"} --не используется --[[ local time_units = {"second", "minute", "hour", "day_of_month", "day_of_week", "day_of_year", "week", "month", "year", "year_of_century", "century"} ]]-- -- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"} local month_lang = { ["ru_G"] = {"января","февраля","марта","апреля","мая","июня", "июля","августа","сентября","октября","ноября","декабря"}, ["ru_N"] = {"январь","февраль","март","апрель","май","июнь", "июль","август","сентябрь","октябрь","ноябрь","декабрь"}, ["en"] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}, ["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}, ["de"] = {"januar", "februar", "märz", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "dezember"}, ["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"} } -- заполняется автоматически local reverse_month_lang = {} -- вспомогательная функция для обращения таблиц (смена ключей со значениями) local reverse_table = function (strait_table) local reversed_table = {} for k,v in pairs(strait_table) do reversed_table[v] = k end return reversed_table end -- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат local filling_months = function (mnlang, month_lang) for i=1, #mnlang do reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]]) end end -- 10) Блок общих функций local function trim(str) if not str then return nil else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)' end end local function purif(str) if str == "" or str == nil then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else return nil end -- need .5 -- ,5 number format converter? end local function is(str) if (not str) or (str == "") then return false else return yesno(str,false) end end local function init(num) local output = {} for i=1,num do table.insert(output, {["year"]="", ["month"]="", ["day"]=""}) end return unpack(output) end local function isyear(tbl) if type(tbl) ~= 'table' then return false elseif not tbl["year"] then return false elseif type(tbl["year"]) == 'number' then return true else return false end end local function inbord(val, down, up) return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up) end local function shallowcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[orig_key] = orig_value end else -- number, string, boolean, etc copy = orig end return copy end local inlist = function ( var, list ) local n = #list local inlist = false for i=1,n do if var == list[i] then inlist = true end end return inlist end -- 20) Блок общих проверочных функций, связанных с датами local function unwarp(tbl) if not tbl then return "" elseif type(tbl) ~= "table" then return tbl elseif (tbl.day or tbl.month or tbl.year) then return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?") else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?") end end local function leap_year(y,jul) if (not y) or (type(y) ~= "number") then return false elseif (y % 4) ~= 0 then return false elseif not jul and (y % 100 == 0 and y % 400 ~= 0) then return false else return true end end -- функция для вычисления последнего дня месяца для юлианского и григорианского календарей local function month_end_day (month,year,is_julian) local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil elseif month ~= 2 or not year then return month_end_day[month] elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29 elseif month == 2 then return 28 else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях end end local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year if not chain then return false elseif (not type(chain) == "table") or (not inbord(chain.year,-9999,9999)) or (not inbord(chain.month,1,12)) or (not inbord(chain.day,1,31)) or chain.day > monthd[chain.month] -- or chain.year == 0 then return false elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul) then return false else return true end -- check for other calendars needed? end local function ispartdate ( chain ) if not chain then return false elseif not (type(chain) == "table") then return false elseif (inbord(chain.year,-9999,9999) or inbord(chain.month,1,12) or inbord(chain.day,1,31)) then return true else return false end -- partial date -- more detailed check for 31.02.0000 needed -- check for other calendars needed end -- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed) local function partdist(date1,date2) local mont, dist = 0, 0 local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "") if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end -- нужна доп. проверка частичных дат на корректность if (inbord(d1m,1,12) or inbord(d2m,1,12)) and (d1m == "" or d2m == "") then mont = purif(date1["month"] or date2["month"]) d1m, d2m = mont, mont end -- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m ) if (inbord(d1m,1,12) and d1d <= monthd[d1m]) and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then if d2m == d1m then dist = d2d - d1d else dist = monthd[d1m] - d1d + d2d end return dist else return math.huge end end local function dmdist(d1,d2) local p1,p2 = math.huge,math.huge if not not partdist(d1,d2) then p1=partdist(d1,d2) end if not not partdist(d2,d1) then p1=partdist(d2,d1) end -- if (not p1) or (not p2) then -- return (p1 or "") .. (p2 or "") -- else -- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2)) return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge) -- end end -- 30) Блок функций для обработки ввода-вывода дат local function undate(tbl) if not tbl then return "" else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "") end end -- функция для нормализации значений дат и перевода месяцев в числа local function numerize(str) if type(str) == "number" then return math.floor(str) elseif str == "" or str == nil or type(str) ~= "string" then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else for i=1, #mnlang do if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)] end end end end -- функция распознавания даты, переданной одной строкой local function parse_date(date_string) if type(date_string) ~= "string" or date_string == "" then return nil end local out_date_str = {"","",""} local error_data = {} for i=1, #pattern do local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1]) if (result_1 or "") > "" then out_date_str[pattern[i].order[1]] = result_1 out_date_str[pattern[i].order[2]] = result_2 if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end -- mw.log("Паттерн " .. i .. ", строка: " .. date_string) break end end local date = { ["day"] =numerize(out_date_str[1]), ["month"]=numerize(out_date_str[2]), ["year"] =numerize(out_date_str[3])} return date --, error_data end ----[[ УСТАРЕЛО ]]---- local numstr2date = function(numstr) local format = "Y-m-d" local iso_date = mwlang:formatDate(format,numstr) local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)") local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)} return dateout end --local numstr2date = function(numstr) -- local nums = {} -- local dateout = {} -- for num in string.gmatch(numstr,"(%d+)") do -- table.insert(nums,purif(num)) -- end -- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums) -- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден") -- elseif not inbord(nums[3],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- elseif not inbord(nums[1],1,31) then -- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]} -- elseif inbord(nums[1],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- else -- local mwlang = mw.getContentLanguage() -- implement mwlang:formatDate(format,datein,true) here -- return error("Не распознано " .. numstr .. " как дата") -- end -- return dateout --end local function year2lang(numyear,yearmark,wiki) if not numyear then return "" end if not yearmark then yearmark = "" end local output = "" local bcmark = " до н. э." if numyear > 0 then bcmark = "" else numyear = 1 - numyear end if wiki then -- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark}) output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'}) else output = tCon({numyear, " ", yearmark, bcmark}) end return trim(output) end local function day2lang(datein,wikidate,wiki,inner_brt) -- if not isdate(wikidate) then wiki = false end if not ispartdate(datein) then return "" end local dm_separ, output = "", nil if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end if (not datein.month) then datein.month = "" end if (not datein.day) then datein.day = "" end local monlan = monthlang[datein.month] or "" if wiki and not inner_brt then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan, "]]"}) elseif wiki then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan}) else output = tCon({datein.day, dm_separ, monlan}) end return trim(output) end local function triple_txt2date(d,m,y) -- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи -- mw.ustring.match((m or ""),"(%a+)") local msg = "" local year = purif((y or "-"):match("(%d+)")) local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))]) local day = purif((d or "-"):match("(%d+)")) if not month then msg = category.incomplete_parameters month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")]) end if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then msg = category.incomplete_parameters day = purif(m:match("(%d+)") or "") end if not year then msg = category.incomplete_parameters year = purif(string.match(m or "","(%d+)") or "") end local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg} return dateout end local function glue(d1,m1,y1,d2,m2,y2) if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then return category.incomplete_parameters end local gd,gm,gy,jd,jm,jy = (d1 or ""), (m1 or ""), (y1 or ""), (d2 or ""), (m2 or ""), (y2 or "") --mw.log(tCon({gd,gm,gy,jd,jm,jy})) local gm_sep = {" [["," год|","]]"} if (not gy) or (gy == "") then gm_sep = {"","",""} end return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ), comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""), gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters}) end -- добавить отображение без года local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) local msg = "" msg = (jdate.msg or "") .. (gdate.msg or "") local cd = {} local jd = shallowcopy(jdate) local gd = shallowcopy(gdate) local left = "(" local right = ")" if sq_brts then left = "&#091;" right = "&#093;" end if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата") elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end if jd.year == gd.year then cd.year = gd.year gd.year, jd.year = nil, nil end if jd.month == gd.month then cd.month = gd.month gd.month, jd.month = nil, nil end if (not not cd.month) and wm then return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end -- 40) Блок функций для перевода дат с использованием [[Юлианская дата]] local function gri2jd( datein ) if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1931076.5, 5373557.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2jul( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local c = jd + 32082 local d = math.floor((4*c + 3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e + 2)/153) local year_out = d - 4800 + math.floor(m/10) local month_out = m + 3 - 12*math.floor(m/10) local day_out = e - math.floor((153*m + 2)/5) + 1 -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function jul2jd( datein ) if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - 32083 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1930999.5, 5373484.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2gri( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local a = jd + 32044 local b = math.floor((4*a + 3) / 146097) local c = a - math.floor(146097*b/4) local d = math.floor((4*c+3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e+2)/153) local day_out = e - math.floor((153*m+2)/5)+1 local month_out = m + 3 - 12*math.floor(m/10) local year_out = 100*b + d - 4800 + math.floor(m/10) -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function astroyear(num, bc) if not num then return error() elseif type(num) ~= "number" then return error() end if num < 1 then return num end if not bc then return num else return 1 - num end end local function recalc(datein,calend) if inlist(calend,params[1]) then return jd2jul(gri2jd(datein)), datein elseif inlist(calend,params[2]) then return datein, jd2gri(jul2jd(datein)) else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," ")) end end -- 50) Функции для обработки UTC local function utc(str,margin) local d = 1 local dchar = "+" local beginning = "[[UTC" local ending = "]]" local cat = "" local nums = {} local hmarg, timedec = 0, 0 local mmarg = "00" local output = "" -- checking type of input if not margin then margin = 0 elseif type(tonumber(margin)) ~= 'number' then output = "Can't shift by " .. margin error(output) end if type(str) ~= 'string' then error("Нет входящей строки") elseif str:byte(1) == 43 then elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]" elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1 else error(string.char(str:byte(1)) .. " недопустимый первый символ") end -- parsing input for num in string.gmatch(str,"(%d+)") do table.insert(nums,purif(num)) end if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums) elseif #nums == 0 then error("Необходимо что-то ввести") elseif #nums == 1 then if inbord(nums[1],0,14) then timedec = d*nums[1] + margin else error("Только часы от -14 до 14") end elseif #nums == 2 then if not inbord(nums[1],0,14) then error("Только часы от -14 до 14") elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59") else timedec = d*(nums[1] + nums[2]/60) + margin end end if tonumber(timedec) == purif(timedec) then hmarg = timedec else local h, m = math.modf(math.abs(timedec)) hmarg = h mmarg = math.floor(m*60) end if timedec == 0 then dchar = "±" elseif timedec > 0 then elseif timedec < 0 then dchar = "&minus;" end -- output output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat return output end -- 60) Блок функций ввода-вывода function p.NthDay( frame ) local args = getArgs(frame, { frameOnly = true }) local num, wday, mont, yea, format = purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5] if not format then format = "%d.%m.%y" end if not inbord(num,-5,5) then return error("The number must be between -5 and 5") elseif num == 0 then return error("The number must not be zero") end if not inbord(wday,0,6) then return error("The day of the week must be between 0 and 6") end if not inbord(mont,1,12) then return error("The month must be between 1 and 12") end if not inbord(yea,0,9999) then return error("Wrong year number") end if inbord(num,1,5) then local m_start = os.time{year=yea, month=mont, day=1, hour=0} local m_wds = tonumber(os.date("%w", m_start)) local start_shift = ( (num - bool_to_number[wday >= m_wds]) * 7 - (m_wds - wday) ) * 24 * 60 * 60 local tim = m_start + start_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end elseif inbord(num,-5,-1) then local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60 local m_wde = tonumber(os.date("%w", m_end)) local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7 + (m_wde - wday)) * 24 * 60 * 60 local tim = m_end - end_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end end end -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) function p.ToIso( frame ) local args = getArgs(frame, { frameOnly = true }) local datein = args[1] -- инициализация, заполнение обратных таблиц, копирование параметров filling_months(mnlang, month_lang) -- парсинг входящей даты по шаблону local date = parse_date(datein) if not (type(date.year) == 'number') then return ("Wrong year: " .. unwarp(date)) end if not (1 <= date.month and date.month <= 12) then return ("Wrong month: " .. unwarp(date)) end if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then return ("Wrong day: " .. unwarp(date)) end local timedate = os.time{year=date.year, month=date.month, day=date.day} local date = os.date("%Y-%m-%d", timedate) return date end -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}}) function p.BoxDate( frame ) local args = getArgs(frame, { frameOnly = true }) local txtDateIn, strFormat = args[1], args[2] local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end function p.bxDate( txtDateIn , strFormat, params ) -- к отладке local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""} strFormat = strFormat or "j xg Y" -- заглушка - таблица параметров на будущее params = params or {} if not txtDateIn then status.errorText = e.no_data status.errorCat = category.no_parameters status.brk = true else -- заполнение служебных таблиц filling_months(mnlang, month_lang) end if not status.brk then -- парсинг входящей даты по шаблону date = parse_date(txtDateIn) -- заменить сообщения об ошибках на списочные if not (date.year and type(date.year) == 'number') then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not inbord(date.month,1,12) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not date.day and string.find(strFormat,"[dDjlNwzW]") then strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]","")) elseif not date.day then elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end end if not status.brk then txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true) end return txtDateOut, date, status end function p.ToDate( frame ) -- возможно неиспользуемая local args = getArgs(frame, { frameOnly = true }) local mwlang = mw.getContentLanguage() local datein = args[1] local format = "j xg Y" if not string.match(datein, "%p") then return datein elseif not args[2] then else format = args[2] end return mwlang:formatDate(format,datein,true) end -- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}}) function p.unitime( frame ) local args = getArgs(frame, { frameOnly = true }) local DST = 0 if not args[2] then else DST = 1 end local utcin = "" local input = args[1] if not input then return "" end if inlist(input:upper(),tzs_names) then utcin = known_tzs[input:upper()] elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then utcin = string.sub(input,4) else if string.sub(input,1,1) == '[' or string.sub(input,1,1) == '{' or string.sub(input,1,1):upper() == 'U' or string.sub(input,1,1):upper() == 'M' then return input -- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or -- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then -- return input else utcin = input end end -- elseif string.sub(input,1,3) ~= "−" then utcin = input -- or not (not input:find("[А-я]")) при наличии в строке юникода не работает local output = "" if DST == 0 then output = utc(utcin) else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST) end return output end -- УСТАРЕЛО -- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) function p.OldDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local gdate, jdate = {}, {} local strin = args[1] local cal = args[2]:lower() or "г" local bc = is(args["bc"]) local wd = is(args["wd"]) local wm = is(args["wm"]) local wy = is(args["wy"]) if not wd then wm = false end local sq_brts = is(args["sq_brts"]) local yearmark = "года" if yesno(args["yearmark"]) then elseif yesno(args["yearmark"]) == false then yearmark = "" else yearmark = trim(args["yearmark"]) or "года" end -- local infocard = is(args["infocard"]) -- local catName = args["catName"] or false local datein = numstr2date(strin) datein.year = astroyear(datein.year, bc) jdate, gdate = recalc(datein,cal) return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}}) function p.NewDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local strin = args[1] local year, month, day if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" ) elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) end if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy") end local cal = "г" if (not args[2]) or (args[2] == "") then cal = "г" else cal = args[2]:lower() end local bc,wd,wm,wy,sq_brts = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]) year = astroyear(purif(year),bc) local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)} local jdate, gdate = recalc(datein,cal) local yearmark = "года" local ym = args["yearmark"] or "" if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}}) -- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}} function p.Test( frame ) local args = getArgs(frame, { frameOnly = true }) -- необходима проверка и замена nil на " " --[[mw.log((args[1] or "") .. " " .. (args[2] or "") .. " " .. (args[3] or "") .. " " .. (args[4] or "") .. " " .. (args[5] or "") .. " " .. (args[6] or "")) ]]-- local ingdate = triple_txt2date(args[1],args[2],args[3]) local injdate = triple_txt2date(args[4],args[5],args[6]) local j1date, g1date, j2date, g2date = init(4) mw.log("ingdate-".. (undate(ingdate) or "")) mw.log("injdate-".. (undate(injdate) or "")) local bc,wd,wm,wy,sq_brts,ny = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]), is(args["ny"]) -- подавление формата для локальных тестов local wd, wm, wy = true, true, true local yearmark = "года" local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "") -- mw.log("ym " .. ym) if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end if isdate(ingdate) or isdate(injdate) then if isdate(ingdate) then j1date, g1date = recalc(ingdate,"g") ingdate["full"] = true end if isdate(injdate) then j2date, g2date = recalc(injdate,"j") injdate["full"] = true end if ispartdate(ingdate) and ispartdate(injdate) then mw.log("📏 " .. dmdist(ingdate,injdate)) mw.log("📏 " .. dmdist(j1date,g1date)) mw.log("📏 " .. dmdist(j2date,g2date)) mw.log("📏 " .. dmdist(ingdate,g1date)) mw.log("📏 " .. dmdist(injdate,j2date)) end end if ny then if isyear(j1date) then else j1date["year"] = "" end if isyear(j2date) == nil then else j2date["year"] = "" end if isyear(g1date) == nil then else g1date["year"] = "" end if isyear(g2date) == nil then else g2date["year"] = "" end end if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then if ((j1date.year == j2date.year) and (j1date.month == j2date.month) and (j1date.day == j2date.day)) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) else mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- категория (предположительная разница в днях) и частичный вывод end elseif isdate(j1date) and isdate(g1date) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif isdate(j2date) and isdate(g2date) then return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif (ispartdate(ingdate) and ispartdate(injdate)) then mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- частичный или полный вывод, категория else mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) return err .. category.incomplete_parameters end end return p a4a91f134ad3e3b246b3a6681a4ae438da766df4 Модуль:Message box/configuration 828 18 47 46 2025-01-31T15:23:59Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = { class = 'ambox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'ambox-delete', image = 'Stop hand nuvola.svg' }, content = { class = 'ambox-content', image = 'Emblem-important.svg' }, style = { class = 'ambox-style', image = 'Broom_icon.svg' }, move = { class = 'ambox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'ambox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'ambox-notice', image = 'Information.svg' }, good = { class = 'ambox-good', image = 'Green star boxed.svg' }, serious = { class = 'ambox-serious', image = 'Stop hand nuvola.svg' }, merge = { class = 'ambox-merge', image = 'Merge-split-transwiki default.svg' }, discussion = { class = 'ambox-discussion', image = 'Nuvola apps ksirc.png' } }, default = 'notice', allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'}, allowSmall = true, smallParam = 'left', smallClass = 'mbox-small-left', substCheck = true, classes = {'metadata', 'ambox'}, imageEmptyCell = true, imageCheckBlank = true, imageSmallSize = '20x20px', imageCellDiv = true, useCollapsibleTextFields = true, imageRightNone = true, sectionDefault = 'статья', allowMainspaceCategories = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для статей', templateCategoryRequireName = true, templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами', templateErrorParamsToCheck = {'issue', 'fix'}, removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]', templatestyles = 'Module:Message box/ambox.css', }, cmbox = { types = { speedy = { class = 'cmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'cmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'cmbox-content', image = 'Ambox important.svg' }, style = { class = 'cmbox-style', image = 'Edit-clear.svg' }, move = { class = 'cmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'cmbox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'cmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'cmbox'}, imageEmptyCell = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/cmbox.css', }, fmbox = { types = { warning = { class = 'fmbox-warning', image = 'Ambox warning pn.svg' }, editnotice = { class = 'fmbox-editnotice', image = 'Information icon4.svg' }, system = { class = 'fmbox-system', image = 'Information icon4.svg' } }, default = 'system', showInvalidTypeError = true, classes = {'fmbox'}, imageEmptyCell = false, imageRightNone = false, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/fmbox.css', }, imbox = { types = { speedy = { class = 'imbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'imbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'imbox-content', image = 'Ambox important.svg' }, style = { class = 'imbox-style', image = 'Edit-clear.svg' }, move = { class = 'imbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'imbox-protection', image = 'Padlock-silver-medium.svg' }, license = { class = 'imbox-license licensetpl', image = 'Imbox license.png' -- @todo We need an SVG version of this }, featured = { class = 'imbox-featured', image = 'Cscr-featured.svg' }, notice = { class = 'imbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'imbox'}, imageEmptyCell = true, below = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов', templatestyles = 'Module:Message box/imbox.css', }, ombox = { types = { speedy = { class = 'ombox-speedy', image = 'OOjs UI icon alert-destructive.svg' }, delete = { class = 'ombox-delete', image = 'OOjs UI icon alert-destructive.svg' }, content = { class = 'ombox-content', image = 'OOjs UI icon notice-warning.svg' }, style = { class = 'ombox-style', image = 'Edit-clear.svg' }, move = { class = 'ombox-move', image = 'Imbox move.png' }, protection = { class = 'ombox-protection', image = 'Imbox protection.png' }, notice = { class = 'ombox-notice', image = 'OOjs UI icon info-progressive.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'ombox'}, allowSmall = true, imageEmptyCell = true, imageRightNone = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/ombox.css', }, tmbox = { types = { speedy = { class = 'tmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'tmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'tmbox-content', image = 'Ambox important.svg' }, style = { class = 'tmbox-style', image = 'Edit-clear.svg' }, move = { class = 'tmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'tmbox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'tmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'tmbox'}, allowSmall = true, imageRightNone = true, imageEmptyCell = true, imageEmptyCellStyle = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений', templatestyles = 'Module:Message box/tmbox.css', } } 2c0750ec1561e8ec25c0988c411f3c69e4957483 Модуль:Category handler/data 828 19 49 48 2025-01-31T15:24:00Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- This module assembles data to be passed to [[Module:Category handler]] using -- mw.loadData. This includes the configuration data and whether the current -- page matches the title blacklist. local data = require('Module:Category handler/config') local mShared = require('Module:Category handler/shared') local blacklist = require('Module:Category handler/blacklist') local title = mw.title.getCurrentTitle() data.currentTitleMatchesBlacklist = mShared.matchesBlacklist( title.prefixedText, blacklist ) data.currentTitleNamespaceParameters = mShared.getNamespaceParameters( title, mShared.getParamMappings() ) return data abbc68048ff698e88dda06b64ecf384bbf583120 Модуль:Category handler/config 828 20 51 50 2025-01-31T15:24:00Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- [[Module:Category handler]] configuration data -- -- Language-specific parameter names and values can be set here. -- -- For blacklist config, see [[Module:Category handler/blacklist]]. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Start configuration data -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- foo = 'parameter name', -- -- -- -- To add multiple names, you can use this format: -- -- -- -- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, -- -------------------------------------------------------------------------------- cfg.parameters = { -- The nocat and categories parameter suppress -- categorisation. They are used with Module:Yesno, and work as follows: -- -- cfg.nocat: -- Result of yesno() Effect -- true Categorisation is suppressed -- false Categorisation is allowed, and -- the blacklist check is skipped -- nil Categorisation is allowed -- -- cfg.categories: -- Result of yesno() Effect -- true Categorisation is allowed, and -- the blacklist check is skipped -- false Categorisation is suppressed -- nil Categorisation is allowed nocat = 'nocat', categories = 'categories', -- The parameter name for the legacy "category2" parameter. This skips the -- blacklist if set to the cfg.category2Yes value, and suppresses -- categorisation if present but equal to anything other than -- cfg.category2Yes or cfg.category2Negative. category2 = 'category2', -- cfg.subpage is the parameter name to specify how to behave on subpages. subpage = 'subpage', -- The parameter for data to return in all namespaces. all = 'all', -- The parameter name for data to return if no data is specified for the -- namespace that is detected. other = 'other', -- The parameter name used to specify a page other than the current page; -- used for testing and demonstration. demopage = 'page', } -------------------------------------------------------------------------------- -- Parameter values -- -- These are set values that can be used with certain parameters. Only one -- -- value can be specified, like this: -- -- -- -- cfg.foo = 'value name' -- -- -------------------------------------------------------------------------------- -- The following settings are used with the cfg.category2 parameter. Setting -- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2 -- is present but equal to anything other than cfg.category2Yes or -- cfg.category2Negative then it supresses cateogrisation. cfg.category2Yes = 'yes' cfg.category2Negative = '¬' -- The following settings are used with the cfg.subpage parameter. -- cfg.subpageNo is the value to specify to not categorise on subpages; -- cfg.subpageOnly is the value to specify to only categorise on subpages. cfg.subpageNo = 'no' cfg.subpageOnly = 'only' -------------------------------------------------------------------------------- -- Default namespaces -- -- This is a table of namespaces to categorise by default. The keys are the -- -- namespace numbers. -- -------------------------------------------------------------------------------- cfg.defaultNamespaces = { [ 0] = true, -- main [ 6] = true, -- file [ 12] = true, -- help [ 14] = true, -- category [100] = true, -- portal [108] = true, -- book } -------------------------------------------------------------------------------- -- Wrappers -- -- This is a wrapper template or a list of wrapper templates to be passed to -- -- [[Module:Arguments]]. -- -------------------------------------------------------------------------------- cfg.wrappers = 'Template:Category handler' -------------------------------------------------------------------------------- -- End configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 373cd107b13a5b00e6a1b7e66a749f12502c849d Модуль:Category handler/shared 828 21 53 52 2025-01-31T15:24:02Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- This module contains shared functions used by [[Module:Category handler]] -- and its submodules. local p = {} function p.matchesBlacklist(page, blacklist) for i, pattern in ipairs(blacklist) do local match = mw.ustring.match(page, pattern) if match then return true end end return false end function p.getParamMappings(useLoadData) local dataPage = 'Module:Namespace detect/data' if useLoadData then return mw.loadData(dataPage).mappings else return require(dataPage).mappings end end function p.getNamespaceParameters(titleObj, mappings) -- We don't use title.nsText for the namespace name because it adds -- underscores. local mappingsKey if titleObj.isTalkPage then mappingsKey = 'talk' else mappingsKey = mw.site.namespaces[titleObj.namespace].name end mappingsKey = mw.ustring.lower(mappingsKey) return mappings[mappingsKey] or {} end return p d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5 Модуль:Category handler/blacklist 828 22 55 54 2025-01-31T15:24:02Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- This module contains the blacklist used by [[Module:Category handler]]. -- Pages that match Lua patterns in this list will not be categorised unless -- categorisation is explicitly requested. return { '^Main Page$', -- don't categorise the main page. -- Don't categorise the following pages or their subpages. -- "%f[/\0]" matches if the next character is "/" or the end of the string. '^Wikipedia:Cascade%-protected items%f[/\0]', '^User:UBX%f[/\0]', -- The userbox "template" space. '^User talk:UBX%f[/\0]', -- Don't categorise subpages of these pages, but allow -- categorisation of the base page. '^Wikipedia:Template messages/.*$', '/[aA]rchive' -- Don't categorise archives. } c84948ad9808d5d323408d5d10d5652f748a0550 Модуль:Namespace detect/data 828 23 57 56 2025-01-31T15:24:02Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect data -- -- This module holds data for [[Module:Namespace detect]] to be loaded per -- -- page, rather than per #invoke, for performance reasons. -- -------------------------------------------------------------------------------- local cfg = require('Module:Namespace detect/config') local function addKey(t, key, defaultKey) if key ~= defaultKey then t[#t + 1] = key end end -- Get a table of parameters to query for each default parameter name. -- This allows wikis to customise parameter names in the cfg table while -- ensuring that default parameter names will always work. The cfg table -- values can be added as a string, or as an array of strings. local defaultKeys = { 'main', 'talk', 'other', 'subjectns', 'demospace', 'demopage' } local argKeys = {} for i, defaultKey in ipairs(defaultKeys) do argKeys[defaultKey] = {defaultKey} end for defaultKey, t in pairs(argKeys) do local cfgValue = cfg[defaultKey] local cfgValueType = type(cfgValue) if cfgValueType == 'string' then addKey(t, cfgValue, defaultKey) elseif cfgValueType == 'table' then for i, key in ipairs(cfgValue) do addKey(t, key, defaultKey) end end cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more. end local function getParamMappings() --[[ -- Returns a table of how parameter names map to namespace names. The keys -- are the actual namespace names, in lower case, and the values are the -- possible parameter names for that namespace, also in lower case. The -- table entries are structured like this: -- { -- [''] = {'main'}, -- ['wikipedia'] = {'wikipedia', 'project', 'wp'}, -- ... -- } --]] local mappings = {} local mainNsName = mw.site.subjectNamespaces[0].name mainNsName = mw.ustring.lower(mainNsName) mappings[mainNsName] = mw.clone(argKeys.main) mappings['talk'] = mw.clone(argKeys.talk) for nsid, ns in pairs(mw.site.subjectNamespaces) do if nsid ~= 0 then -- Exclude main namespace. local nsname = mw.ustring.lower(ns.name) local canonicalName = mw.ustring.lower(ns.canonicalName) mappings[nsname] = {nsname} if canonicalName ~= nsname then table.insert(mappings[nsname], canonicalName) end for _, alias in ipairs(ns.aliases) do table.insert(mappings[nsname], mw.ustring.lower(alias)) end end end return mappings end return { argKeys = argKeys, cfg = cfg, mappings = getParamMappings() } d224f42a258bc308ef3ad8cc8686cd7a4f47d005 Модуль:Namespace detect/config 828 24 59 58 2025-01-31T15:24:03Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect configuration data -- -- -- -- This module stores configuration data for Module:Namespace detect. Here -- -- you can localise the module to your wiki's language. -- -- -- -- To activate a configuration item, you need to uncomment it. This means -- -- that you need to remove the text "-- " at the start of the line. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. Values added -- -- here will work in addition to the default English parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- cfg.foo = 'parameter name' -- -- -- -- To add multiple names, you can use this format: -- -- -- -- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} -- -------------------------------------------------------------------------------- ---- This parameter displays content for the main namespace: -- cfg.main = 'main' ---- This parameter displays in talk namespaces: -- cfg.talk = 'talk' ---- This parameter displays content for "other" namespaces (namespaces for which ---- parameters have not been specified): -- cfg.other = 'other' ---- This parameter makes talk pages behave as though they are the corresponding ---- subject namespace. Note that this parameter is used with [[Module:Yesno]]. ---- Edit that module to change the default values of "yes", "no", etc. -- cfg.subjectns = 'subjectns' ---- This parameter sets a demonstration namespace: -- cfg.demospace = 'demospace' ---- This parameter sets a specific page to compare: cfg.demopage = 'page' -------------------------------------------------------------------------------- -- Table configuration -- -- These configuration items allow customisation of the "table" function, -- -- used to generate a table of possible parameters in the module -- -- documentation. -- -------------------------------------------------------------------------------- ---- The header for the namespace column in the wikitable containing the list of ---- possible subject-space parameters. -- cfg.wikitableNamespaceHeader = 'Namespace' ---- The header for the wikitable containing the list of possible subject-space ---- parameters. -- cfg.wikitableAliasesHeader = 'Aliases' -------------------------------------------------------------------------------- -- End of configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 0e4ff08d13c4b664d66b32c232deb129b77c1a56 Шаблон:Yesno 10 25 61 60 2025-01-31T15:24:03Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }} |no |n |нет |false |0 = {{{no|<!-- null -->}}} | = {{{blank|{{{no|<!-- null -->}}}}}} |¬ = {{{¬|}}} |yes |y |да |true |1 = {{{yes|yes}}} |#default = {{{def|{{{yes|yes}}}}}} }}<noinclude> {{Documentation}} </noinclude> 4e236854c477d07a225c2ab6c016c389b133e8d3 Шаблон:Карточка/внизу 10 26 63 62 2025-01-31T15:24:03Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude> {{doc}} </noinclude> 169fb2d10b0847c2fd677eda9f159ba99025198f Модуль:String 828 27 65 64 2025-01-31T15:24:04Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain --[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 'true' or 1, any error condition will result in an empty string being returned rather than an error message. error_category: If an error occurs, specifies the name of a category to include with the error message. The default category is [Category:Errors reported by Module String]. no_category: If set to 'true' or 1, no category will be added if an error is generated. Unit tests for this module are available at Module:String/tests. ]] local str = {} --[[ subcount This function returns the count of substring in source string. Usage: {{#invoke:String|subcount|source_string|substring|plain_flag}} OR {{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}} Parameters s: The string to search pattern: The pattern or string to find within the string plain: A flag indicating that the substring should be understood as plain text. Defaults to true. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.subcount( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} ); local s = new_args['s'] or ''; local plain_flag = str._getBoolean( new_args['plain'] or true ); local pattern = new_args['pattern'] or ''; if s == '' or pattern == '' then return 0; end if plain_flag then pattern = str._escapePattern( pattern ); end local _, count = mw.ustring.gsub(s, pattern, "") return count; end --[[ len This function returns the length of the target string. Usage: {{#invoke:String|len|target_string|}} OR {{#invoke:String|len|s=target_string}} Parameters s: The string whose length to report If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.len( frame ) local new_args = str._getParameters( frame.args, {'s'} ); local s = new_args['s'] or ''; return mw.ustring.len( s ) end --[[ sub This function returns a substring of the target string at specified indices. Usage: {{#invoke:String|sub|target_string|start_index|end_index}} OR {{#invoke:String|sub|s=target_string|i=start_index|j=end_index}} Parameters s: The string to return a subset of i: The fist index of the substring to return, defaults to 1. j: The last index of the string to return, defaults to the last character. The first character of the string is assigned an index of 1. If either i or j is a negative value, it is interpreted the same as selecting a character by counting from the end of the string. Hence, a value of -1 is the same as selecting the last character of the string. If the requested indices are out of range for the given string, an error is reported. ]] function str.sub( frame ) local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } ); local s = new_args['s'] or ''; local i = tonumber( new_args['i'] ) or 1; local j = tonumber( new_args['j'] ) or -1; local len = mw.ustring.len( s ); -- Convert negatives for range checking if i < 0 then i = len + i + 1; end if j < 0 then j = len + j + 1; end if i > len or j > len or i < 1 or j < 1 then return str._error( 'Значение индекса подстроки выходит за допустимые границы' ); end if j < i then return str._error( 'Неверный порядок индексов подстроки' ); end return mw.ustring.sub( s, i, j ) end --[[ This function implements that features of {{str sub old}} and is kept in order to maintain these older templates. ]] function str.sublength( frame ) local i = tonumber( frame.args.i ) or 0 local len = tonumber( frame.args.len ) return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) end --[[ match This function returns a substring from the source string that matches a specified pattern. Usage: {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} OR {{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index |match=match_number|plain=plain_flag|nomatch=nomatch_output}} Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from each string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. If the match_number or start_index are out of range for the string being queried, then this function generates an error. An error is also generated if no match is found. If one adds the parameter ignore_errors=true, then the error will be suppressed and an empty string will be returned on any failure. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] function str.match( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} ); local s = new_args['s'] or ''; local start = tonumber( new_args['start'] ) or 1; local plain_flag = str._getBoolean( new_args['plain'] or false ); local pattern = new_args['pattern'] or ''; local match_index = math.floor( tonumber(new_args['match']) or 1 ); local nomatch = new_args['nomatch']; if s == '' then return str._error( 'Пустая строка поиска' ); end if pattern == '' then return str._error( 'Пустой шаблон поиска' ); end if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then return str._error( 'Индекс начала поиска выходит за допустимые границы' ); end if match_index == 0 then return str._error( 'Индекс совпадения выходит за допустимые границы' ); end if plain_flag then pattern = str._escapePattern( pattern ); end local result if match_index == 1 then -- Find first match is simple case result = mw.ustring.match( s, pattern, start ) else if start > 1 then s = mw.ustring.sub( s, start ); end local iterator = mw.ustring.gmatch(s, pattern); if match_index > 0 then -- Forward search for w in iterator do match_index = match_index - 1; if match_index == 0 then result = w; break; end end else -- Reverse search local result_table = {}; local count = 1; for w in iterator do result_table[count] = w; count = count + 1; end result = result_table[ count + match_index ]; end end if result == nil then if nomatch == nil then return str._error( 'Совпадение не найдено' ); else return nomatch; end else return result; end end --[[ pos This function returns a single character from the target string at position pos. Usage: {{#invoke:String|pos|target_string|index_value}} OR {{#invoke:String|pos|target=target_string|pos=index_value}} Parameters target: The string to search pos: The index for the character to return If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. The first character has an index value of 1. If one requests a negative value, this function will select a character by counting backwards from the end of the string. In other words pos = -1 is the same as asking for the last character. A requested value of zero, or a value greater than the length of the string returns an error. ]] function str.pos( frame ) local new_args = str._getParameters( frame.args, {'target', 'pos'} ); local target_str = new_args['target'] or ''; local pos = tonumber( new_args['pos'] ) or 0; if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then return str._error( 'Значение индекса строки выходит за допустимые границы' ); end return mw.ustring.sub( target_str, pos, pos ); end --[[ str_find This function duplicates the behavior of {{str_find}}, including all of its quirks. This is provided in order to support existing templates, but is NOT RECOMMENDED for new code and templates. New code is recommended to use the "find" function instead. Returns the first index in "source" that is a match to "target". Indexing is 1-based, and the function returns -1 if the "target" string is not present in "source". Important Note: If the "target" string is empty / missing, this function returns a value of "1", which is generally unexpected behavior, and must be accounted for separatetly. ]] function str.str_find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target'} ); local source_str = new_args['source'] or ''; local target_str = new_args['target'] or ''; if target_str == '' then return 1; end local start = mw.ustring.find( source_str, target_str, 1, true ) if start == nil then start = -1 end return start end --[[ find This function allows one to search for a target string or pattern within another string. Usage: {{#invoke:String|find|source_str|target_string|start_index|plain_flag}} OR {{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}} Parameters source: The string to search target: The string or pattern to find within source start: The index within the source string to start the search, defaults to 1 plain: Boolean flag indicating that target should be understood as plain text and not as a Lua style regular expression, defaults to true If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. This function returns the first index >= "start" where "target" can be found within "source". Indices are 1-based. If "target" is not found, then this function returns 0. If either "source" or "target" are missing / empty, this function also returns 0. This function should be safe for UTF-8 strings. ]] function str.find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['target'] or ''; local start_pos = tonumber(new_args['start']) or 1; local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return 0; end plain = str._getBoolean( plain ); local start = mw.ustring.find( source_str, pattern, start_pos, plain ) if start == nil then start = 0 end return start end --[[ replace This function allows one to replace a target string or pattern within another string. Usage: {{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}} OR {{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string| count=replacement_count|plain=plain_flag}} Parameters source: The string to search pattern: The string or pattern to find within source replace: The replacement text count: The number of occurences to replace, defaults to all. plain: Boolean flag indicating that pattern should be understood as plain text and not as a Lua style regular expression, defaults to true ]] function str.replace( frame ) local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['pattern'] or ''; local replace = new_args['replace'] or ''; local count = tonumber( new_args['count'] ); local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return source_str; end plain = str._getBoolean( plain ); if plain then pattern = str._escapePattern( pattern ); replace = string.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences. end local result; if count ~= nil then result = mw.ustring.gsub( source_str, pattern, replace, count ); else result = mw.ustring.gsub( source_str, pattern, replace ); end return result; end --[[ This function adds support for escaping parts of the patterns when using [plain=false]. ]] function str.escape( frame ) local new_args = str._getParameters( frame.args, {'pattern' } ); local pattern = new_args['pattern'] or ''; local result = ''; result = str._escapePattern( pattern ); return result; end --[[ Internal compare string function ]] function str._strcmp(a , b) local s1c = mw.ustring.gcodepoint( a ); local s2c = mw.ustring.gcodepoint( b ); while true do local c1 = s1c(); local c2 = s2c(); if c1 == nil then if c2 == nil then return 0 else return -1 end else if c2 ~= nil then if c1 ~= c2 then return c1 < c2 and -1 or 1 end else return 1 end end end return 0 end --[[ compare This function compare two UTF-8 strings Usage: {{#invoke:String|compare|str1|str2}} Returns: 0 - if strings are equal 1 - if st1 > str2 -1 - if str1 < str2 ]] function str.compare(frame) local str1 = frame.args[1] or ''; local str2 = frame.args[2] or ''; return str._strcmp(str1 , str2) end --[[ simple function to pipe string.rep to templates. ]] function str.rep( frame ) local repetitions = tonumber( frame.args[2] ) if not repetitions then return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' ) end return string.rep( frame.args[1] or '', repetitions ) end --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function str._getParameters( frame_args, arg_list ) local new_args = {}; local index = 1; local value; for i,arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index]; index = index + 1; end new_args[arg] = value; end return new_args; end --[[ Helper function to handle error messages. ]] function str._error( error_str ) local frame = mw.getCurrentFrame(); local error_category = frame.args.error_category or 'Страницы с ошибками модуля String'; local ignore_errors = frame.args.ignore_errors or false; local no_category = frame.args.no_category or false; if str._getBoolean(ignore_errors) then return ''; end local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>'; if error_category ~= '' and not str._getBoolean( no_category ) then error_str = '[[Категория:' .. error_category .. ']]' .. error_str; end return error_str; end --[[ Helper Function to interpret boolean strings ]] function str._getBoolean( boolean_str ) local boolean_value; if type( boolean_str ) == 'string' then boolean_str = boolean_str:lower(); if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' or boolean_str == '' then boolean_value = false; else boolean_value = true; end elseif type( boolean_str ) == 'boolean' then boolean_value = boolean_str; else error( 'Логическое значение не найдено' ); end return boolean_value end --[[ Helper function that escapes all pattern characters so that they will be treated as plain text. ]] function str._escapePattern( pattern_str ) return ( string.gsub( pattern_str, "[%(%)%.%%%+%-%*%?%[%^%$%]]", "%%%0" ) ) end return str 2c7347f1dafbbc0efc196c148a1f81e7b82420dc Модуль:Infobox 828 28 67 66 2025-01-31T15:24:04Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local p = {}; local yesno = require('Module:Yesno') local function _renderLine( frame, args, i ) if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then return '' elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' ); local class = ( args[ 'класс' .. i ] or '' ); return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' .. args[ 'заголовок' .. i ] .. '</th>\n</tr>'; end if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then return args[ 'блок' .. i ]; end local text = args[ 'текст' .. i ] or ''; if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then text = frame:expandTemplate{ title = 'Wikidata', args = { args[ 'викиданные' .. i ], text, from = args[ 'from' ] or '' } }; end if text ~= '' then local label = args[ 'метка' .. i ] or ''; local class = args[ 'класс' .. i ] or ''; if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then class = class .. ' plainlist'; end if class ~= '' then class = ' class="' .. class .. '"'; end local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' ); if label == '' then style = 'text-align:center;' .. style; end if style ~= '' then style = ' style="' .. style .. '"'; end if label ~= '' then local labelClass = args[ 'класс_меток' ] or ''; if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then labelClass = labelClass .. ' plainlist'; end if labelClass ~= '' then labelClass = ' class="' .. labelClass .. '"'; end local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' ); if labelStyle ~= '' then labelStyle = ' style="' .. labelStyle .. '"'; end return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' .. '\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return ''; end local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.renderLine( frame ) local args = frame:getParent().args; return _renderLine(frame, args, '') end function p.renderLines( frame ) local args = frame:getParent().args; local res = '' local header, text = '', '' local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false) for i = 1, maxNumber(args) do if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then if text ~= '' or not autoHeaders then res = res .. header .. text end header, text = _renderLine(frame, args, i), '' else text = text .. _renderLine(frame, args, i) end end if text ~= '' or not autoHeaders then res = res .. header .. text end return res end return p; c830c997bd3d15923f347277e3b0ae71b7ba917e Модуль:Transclude 828 29 69 68 2025-01-31T15:24:05Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local p={} -- Вызывает внутренний шаблон с аргументами объемлющего шаблона function p.call(frame) local template = frame.args[1] local args = frame:getParent().args return frame:expandTemplate{ title=template, args=args } end -- Общая реализация для forall и call local function forallImpl(args, separator, conjunction, func) -- нумерованные ключи из args local keys = {} -- перебор в произвольном порядке, даже для нумерованных ключей for key, value in pairs(args) do if type(key) == 'number' and value and value ~= '' then table.insert(keys, key) end end table.sort(keys) local results = {} for _, key in ipairs(keys) do local value = func(args[key]) table.insert(results, value) end return mw.text.listToText(results, separator, conjunction) end -- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному function p.forall(frame) local template = frame.args[1] local separator = frame.args.separator or '' local conjunction = frame.args.conjunction or separator local args = frame:getParent().args local func = function(value) return frame:expandTemplate{ title = template, args = {value} } -- или другой frame? end return forallImpl(args, separator, conjunction, func) end -- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку function p.join(frame) local separator = frame.args[1] or '' local conjunction = frame.args[2] or separator local args = frame:getParent().args local func = function(value) return value end return forallImpl(args, separator, conjunction, func) end -- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами local function deleteDuplicates(args) local res = {} for key, value in pairs(args) do if args[key+1] ~= value then table.insert(res, value) end end return res end -- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона function p.npc(frame) local args = frame:getParent().args local templateFrame = frame:getParent() local template = frame.args[1] -- определение, блоки аргументов с какими номерами нужны: -- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок local nums = {} for key, _ in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- учитывать "параметр12", только если задано "параметр" if num and frame.args[main] then table.insert(nums, num) end end table.sort(nums) nums = deleteDuplicates(nums) -- проходить по нужным номерам блоков по возрастанию и однократно -- подставлять в шаблон: -- 1. общие аргументы данного модуля -- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок local results = {} for _, blockNum in ipairs(nums) do -- общие аргументы модуля, которые передаются в каждый блок local blockArgs = mw.clone(frame.args) -- metatable ломает expandTemplate setmetatable(blockArgs, nil) for key, value in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля if blockNum == num and frame.args[main] then blockArgs[main] = value end end local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs } table.insert(results, blockText) end return table.concat(results) end -- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2]. function p.cycle(f) local tf,ac,op=f:getParent(), {}, f.args.output or 'inline'; local sep=''; if op == 'newline' then sep='\n'; end for p,k in pairs(f.args) do if type(p)=='number' then if p>2 then ac[p-1]=k end else ac[p]=k end end local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1, f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or ''; fh=tonumber(fh) or fh:match('^%s*(.-)%s*$'); s=tonumber(s); local acr={}; if not s then error('Начало цикла «'..s..'» — не число') end local function dc(order) local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} } if order == 'desc' then s=s-1; else s=s+1; end if r~='' then table.insert(acr,r); return r end end if type(fh)=='number' then if fh > s then while s<=fh do dc('asc') end else while s>=fh do dc('desc') end end elseif fh~='' then while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end else while dc('asc') do end end return table.concat(acr, sep) end return p c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59 Шаблон:Replace 10 30 71 70 2025-01-31T15:24:05Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude> {{doc}} </noinclude> 7752c3c70ae8c46a89a0808aa282956866dbba5b Шаблон:Str left 10 31 73 72 2025-01-31T15:24:05Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude> {{doc}} </noinclude> c1f57b63826f4d455dcaec8d2c24a2b8268f42ec Шаблон:Join 10 32 75 74 2025-01-31T15:24:06Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude> {{doc}} <!-- Категории — на подстраницу /doc, интервики — в Викиданные. --> </noinclude> 92bb17b5322d3ae0ceab93d4dad3d31810d47eb0 Модуль:Navbox 828 33 77 76 2025-01-31T15:24:07Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- -- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}. -- Основной объём кода заимствован из английского Module:Navbox. -- local p = {} local navbar = require('Module:Navbar')._ruwikiNavbar local getArgs -- lazily initialized local yesno -- lazily initialized local styleratio local ODD_EVEN_MARKER = '\127_ODDEVEN_\127' local RESTART_MARKER = '\127_ODDEVEN0_\127' local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127' -- общие параметры для всех шаблонов local commonAliases = { name = {'name', 'имя'}, navigation = {'navigation', 'навигация'}, navbar = {'navbar', 'ссылка_на_просмотр'}, state = {'state'}, orphan = {'orphan'}, tracking = {'tracking'}, border = {'border', 1}, title = {'title', 'заголовок'}, titlegroup = {'titlegroup'}, above = {'above', 'вверху'}, image = {'image', 'изображение'}, imageleft = {'imageleft', 'изображение2', 'изображение_слева'}, below = {'below', 'внизу'}, bodyclass = {'bodyclass', 'класс_тела'}, titleclass = {'titleclass', 'класс_заголовка'}, titlegroupclass = {'titlegroupclass'}, aboveclass = {'aboveclass', 'класс_вверху'}, belowclass = {'belowclass', 'класс_внизу'}, groupclass = {'groupclass', 'класс_групп'}, listclass = {'listclass', 'класс_списков'}, imageclass = {'imageclass', 'класс_изображения'}, basestyle = {'basestyle', 'стиль', 'стиль_базовый'}, bodystyle = {'style', 'bodystyle', 'стиль_тела'}, titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'}, titlegroupstyle = {'titlegroupstyle'}, innerstyle = {'innerstyle'}, abovestyle = {'abovestyle', 'стиль_вверху'}, belowstyle = {'belowstyle', 'стиль_внизу'}, imagestyle = {'imagestyle', 'стиль_изображения'}, imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} local standardAliases = { groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'}, liststyle = {'liststyle', 'стиль_списков'}, evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'}, groupwidth = {'groupwidth', 'ширина_групп'}, listpadding = {'listpadding', 'отступ_списков'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией local standardElementAliases = { group = {'group%s', 'заголовок%s', 'группа%s'}, list = {'list%s', 'список%s'}, groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'}, listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'}, liststyle = {'list%sstyle', 'стиль_списка%s'}, listpadding = {'list%spadding'} } -- параметры {{навигационная таблица с блоками}} -- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases local groupsParentAliases = { selected = {'selected', 'открытый_блок', 'развернуть'}, secttitlestyle = {'secttitlestyle', 'стиль_заголовков'}, _groupstyle = {'groupstyle', 'стиль_блоков'}, _liststyle = {'liststyle', 'стиль_списков', 'contentstyle'}, _listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'} } -- параметры {{навигационная таблица с блоками}} с нумерацией local groupsChildAliases = { groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'}, state = {'state%s'}, title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'}, list1 = {'list%s', 'список%s', 'content%s'}, image = {'image%s', 'изображение%s'}, imageleft = {'imageleft%s', 'изображение_слева%s'}, secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'}, groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'}, listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'}, liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'}, color = {'цвет%s'} } local function checkAliases(args, aliases, index) for _, alias in ipairs(aliases) do local arg if index then arg = args[string.format(alias, index)] else arg = args[alias] end if arg then return arg end end return nil end local function checkElAliases(args, name, index) return checkAliases(args, standardElementAliases[name], index) end local function concatStyles(t) local res for k, v in pairs(t) do if v then res = res and res .. ';' .. v or v end end return res end local function striped(wikitext, args) -- Return wikitext with markers replaced for odd/even striping. -- Child (subgroup) navboxes are flagged with a category that is removed -- by parent navboxes. The result is that the category shows all pages -- where a child navbox is not contained in a parent navbox. local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]' if args.border == 'subgroup' and args.orphan ~= 'yes' then -- No change; striping occurs in outermost navbox. return wikitext .. orphanCat end local first, second = 'odd', 'even' if args.evenodd then if args.evenodd == 'swap' then first, second = second, first else first = args.evenodd second = first end end local changer if first == second then changer = first else local index = 0 changer = function (code) if code == '0' then -- Current occurrence is for a group before a nested table. -- Set it to first as a valid although pointless class. -- The next occurrence will be the first row after a title -- in a subgroup and will also be first. index = 0 return first end index = index + 1 return index % 2 == 1 and first or second end end local regex = orphanCat:gsub('([%[%]])', '%%%1') return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count end local function addNewline(s) if s:match('^[*:;#]') or s:match('^{|') then return '\n' .. s ..'\n' else return s end end local function renderNavBar(titleCell, args) local currentFrame = mw.getCurrentFrame() if args.navbar ~= 'off' and args.navbar ~= 'plain' and (args.name or not currentFrame:getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then --- Gear creation titleCell :tag('span') :addClass('navbox-gear') :css('float', 'left') :css('text-align', 'left') :css('width', '5em') :css('margin-right', '0.5em') :wikitext(navbar{ args.name, ['fontstyle'] = args.titlestyle or args.basestyle }) end end -- -- Title row -- local function renderTitleRow(tbl, args) if not args.title then return end local titleRow = tbl:tag('tr') if args.titlegroup then titleRow :tag('th') :attr('scope', 'row') :addClass('navbox-group') :addClass(args.titlegroupclass) :cssText(args.basestyle) :cssText(args.groupstyle) :cssText(args.titlegroupstyle) :wikitext(args.titlegroup) end local titleCell = titleRow:tag('th'):attr('scope', 'colgroup') if args.titlegroup then titleCell :css('border-left', '2px solid #fdfdfd') :css('width', '100%') end local titleColspan = 2 if args.imageleft then titleColspan = titleColspan + 1 end if args.image then titleColspan = titleColspan + 1 end if args.titlegroup then titleColspan = titleColspan - 1 end titleCell :cssText(args.basestyle) :cssText(args.titlestyle) :addClass('navbox-title') :attr('colspan', titleColspan) renderNavBar(titleCell, args) titleCell :tag('div') :attr('id', mw.uri.anchorEncode(args.title)) :addClass(args.titleclass) :css('font-size', '114%') :css('margin', '0 5em') :wikitext(addNewline(args.title)) end -- -- Above/Below rows -- local function getAboveBelowColspan(args) local ret = 2 if args.imageleft then ret = ret + 1 end if args.image then ret = ret + 1 end return ret end local function renderAboveRow(tbl, args) if not args.above then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.aboveclass) :cssText(args.basestyle) :cssText(args.abovestyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.above)) end local function renderBelowRow(tbl, args) if not args.below then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.belowclass) :cssText(args.basestyle) :cssText(args.belowstyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.below)) end -- -- List rows -- local function haveSubgroups(args) for i = 1, 23 do if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then return true end end return false end local function renderListRow(tbl, args, index, rowspan, rowArgs) local row = tbl:tag('tr') if index == 1 and args.imageleft then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 7px 0px 0px') :cssText(args.imageleftstyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.imageleft)) end if rowArgs.group then local groupCell = row:tag('th') groupCell :attr('scope', 'row') :addClass('navbox-group') :addClass(args.groupclass) :cssText(args.basestyle) :css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width groupCell :cssText(args.groupstyle) :cssText(rowArgs.groupstyle) :wikitext(rowArgs.group) end local listCell = row:tag('td') if rowArgs.group then listCell :css('text-align', 'left') :css('border-left-width', '2px') :css('border-left-style', 'solid') else if haveSubgroups(args) then listCell :attr('colspan', 2) end end if not args.groupwidth then listCell:css('width', '100%') end local listText = rowArgs.list local oddEven = ODD_EVEN_MARKER if listText:sub(1, 12) == '</div><table' then -- Assume list text is for a subgroup navbox so no automatic striping for this row. oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd' end listCell :css('padding', '0px') :cssText(args.liststyle) :cssText(rowArgs.liststyle) :addClass('navbox-list') :addClass('navbox-' .. oddEven) :addClass(args.listclass) :addClass(rowArgs.listclass) :tag('div') :css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em') :wikitext(addNewline(listText)) if index == 1 and args.image then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 0px 0px 7px') :cssText(args.imagestyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.image)) end end -- -- Tracking categories -- local function needsChangetoSubgroups(args) for i = 1, 23 do if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then return true end end return false end local function needsHorizontalLists(args) if args.border == 'subgroup' or args.tracking == 'no' then return false end local listClasses = { ['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true, ['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true, ['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true, } return not (listClasses[args.listclass] or listClasses[args.bodyclass]) end -- local function hasBackgroundColors() -- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background') -- end local function isIllegible(args) if not styleratio then styleratio = require('Module:Color contrast')._styleratio end for key, style in pairs(args) do if tostring(key):match("style$") or tostring(key):match("^стиль") then if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then return true end end end return false end local function getTrackingCategories(args) local cats = {} if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end return cats end local function renderTrackingCategories(builder, args) local title = mw.title.getCurrentTitle() if title.namespace ~= 10 then return end -- not in template space local subpage = title.subpageText if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end for i, cat in ipairs(getTrackingCategories(args)) do builder:wikitext('[[Категория:' .. cat .. ']]') end end -- -- Main navbox tables -- local function renderMainTable(args, listnums) local tbl = mw.html.create('table') :addClass('nowraplinks') :addClass(args.bodyclass) if args.title and (args.state ~= 'plain' and args.state ~= 'off') then tbl :addClass('collapsible') :addClass(args.state or 'autocollapse') end tbl:css('border-spacing', 0) if args.border == 'subgroup' or args.border == 'none' then tbl :addClass('navbox-subgroup') :cssText(args.bodystyle) else -- regular navbox - bodystyle and style will be applied to the wrapper table tbl :addClass('navbox-inner') :css('background', 'transparent') :css('color', 'inherit') end tbl:cssText(args.innerstyle) renderTitleRow(tbl, args) renderAboveRow(tbl, args) for i, listnum in ipairs(listnums) do local rowArgs = { group = checkElAliases(args, 'group', listnum), list = checkElAliases(args, 'list', listnum), groupstyle = checkElAliases(args, 'groupstyle', listnum), listclass = checkElAliases(args, 'listclass', listnum), liststyle = checkElAliases(args, 'liststyle', listnum), listpadding = checkElAliases(args, 'listpadding', listnum) } renderListRow(tbl, args, i, #listnums, rowArgs) end renderBelowRow(tbl, args) return tbl end -- Read the arguments in the order they'll be output in, to make references number in the right order. local function readInTheRightOrder(args, groupAliases, listAliases) local _ _ = checkAliases(args, commonAliases.title) _ = checkAliases(args, commonAliases.above) for i = 1, 23 do _ = checkAliases(args, groupAliases, i) _ = checkAliases(args, listAliases, i) end _ = checkAliases(args, commonAliases.below) end function p._navbox(args) if not yesno then yesno = require('Module:Yesno') end local listnums = {} for k, v in pairs(args) do local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$') if listnum then table.insert(listnums, tonumber(listnum)) end end table.sort(listnums) args.border = mw.text.trim(args.border or args[1] or '') if args.border == 'child' then args.border = 'subgroup' end for argname, aliasesList in pairs(commonAliases) do args[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(standardAliases) do args[argname] = checkAliases(args, aliasesList) end args.navigation = yesno(args.navigation, '') -- render the main body of the navbox local tbl = renderMainTable(args, listnums) -- render the appropriate wrapper around the navbox, depending on the border param local res = mw.html.create() if args.border == 'none' then local nav = res:tag('div') :attr('role', 'navigation') :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end elseif args.border == 'subgroup' then -- We assume that this navbox is being rendered in a list cell of a parent navbox, and is -- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the -- padding being applied, and at the end add a <div> to balance out the parent's </div> res :wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html. :node(tbl) :wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html. else local nav = res:tag('div') :attr('role', 'navigation') :addClass('navbox') :cssText(args.bodystyle) :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end end renderTrackingCategories(res, args) return striped(tostring(res), args) end function p.navbox(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end if not yesno then yesno = require('Module:Yesno') end args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}}) if frame.args.border then -- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}. args.border = frame.args.border end readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list) return p._navbox(args) end function p.navboxWithCollapsibleGroups(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}}) readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1) local parent = {} for argname, aliasesList in pairs(commonAliases) do parent[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(groupsParentAliases) do parent[argname] = checkAliases(args, aliasesList) end for i = 1, 20 do local child = {} for argname, aliasesList in pairs(groupsChildAliases) do child[argname] = checkAliases(args, aliasesList, i) end child.color = child.color and string.format('background:%s;', child.color) or '' child.border = 'child' child.navbar = 'plain' if parent.selected and parent.selected == child.groupname then child.state = 'uncollapsed' end child.state = child.state or 'collapsed' child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle} child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color} child.liststyle = concatStyles{parent._liststyle, child.liststyle} child.lispadding = parent._listpadding if child.title then parent['list' .. i] = p._navbox(child) else parent['list' .. i] = child.list1 end end return p._navbox(parent) end return p cf72974326d19e1d4d58d2d00766b944b3ca0944 Модуль:Color contrast 828 34 79 78 2025-01-31T15:24:07Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- -- This module implements -- {{Color contrast ratio}} -- {{Greater color contrast ratio}} -- {{ColorToLum}} -- {{RGBColorToLum}} -- local p = {} local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' ) local function sRGB ( v ) if (v <= 0.03928) then v = v / 12.92 else v = math.pow((v+0.055)/1.055, 2.4) end return v end local function rgbdec2lum( R, G, B ) if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255) else return '' end end local function hsl2lum( h, s, l ) if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then local c = (1 - math.abs(2*l - 1))*s local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) ) local m = l - c/2 local r, g, b = m, m, m if( 0 <= h and h < 60 ) then r = r + c g = g + x elseif( 60 <= h and h < 120 ) then r = r + x g = g + c elseif( 120 <= h and h < 180 ) then g = g + c b = b + x elseif( 180 <= h and h < 240 ) then g = g + x b = b + c elseif( 240 <= h and h < 300 ) then r = r + x b = b + c elseif( 300 <= h and h < 360 ) then r = r + c b = b + x end return rgbdec2lum(255*r, 255*g, 255*b) else return '' end end local function color2lum( c ) if (c == nil) then return '' end -- whitespace c = c:match( '^%s*(.-)[%s;]*$' ) -- lowercase c = c:lower() -- first try to look it up local L = HTMLcolor[c] if (L ~= nil) then return L end -- convert from hsl if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100) end -- convert from rgb if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$') return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B)) end -- convert from rgb percent if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100) end -- remove leading # (if there is one) and whitespace c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$') -- split into rgb local cs = mw.text.split(c or '', '') if( #cs == 6 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]) local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]) local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]) return rgbdec2lum(R, G, B) elseif ( #cs == 3 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1]) local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2]) local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3]) return rgbdec2lum(R, G, B) end -- failure, return blank return '' end function p._greatercontrast(args) local bias = tonumber(args['bias'] or '0') or 0 local v1 = color2lum(args[1] or '') local c2 = args[2] or '#FFFFFF' local v2 = color2lum(c2) local c3 = args[3] or '#000000' local v3 = color2lum(c3) local ratio1 = 0; local ratio2 = 0; if (type(v1) == 'number' and type(v2) == 'number') then ratio1 = (v2 + 0.05)/(v1 + 0.05) ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1 end if (type(v1) == 'number' and type(v3) == 'number') then ratio2 = (v3 + 0.05)/(v1 + 0.05) ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2 end return (ratio1 + bias > ratio2) and c2 or c3 end function p._ratio(args) local v1 = color2lum(mw.text.unstripNoWiki(args[1] or '')) local v2 = color2lum(mw.text.unstripNoWiki(args[2] or '')) if (type(v1) == 'number' and type(v2) == 'number') then -- v1 should be the brighter of the two. if v2 > v1 then v1, v2 = v2, v1 end return (v1 + 0.05)/(v2 + 0.05) else return args['error'] or '?' end end function p._styleratio(args) local style = (args[1] or ''):lower() local bg, fg = 'white', '#202122' local lum_bg, lum_fg = 1, 0.016 if args[2] then local lum = color2lum(args[2]) if lum ~= '' then bg, lum_bg = args[2], lum end end if args[3] then local lum = color2lum(args[3]) if lum ~= '' then fg, lum_fg = args[3], lum end end local slist = mw.text.split(style or '', ';') for k = 1, #slist do local s = slist[k] local k, v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' ) k = k or '' v = v or '' if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_bg = v, lum end elseif (k:match('^[%s]*(color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_fg = v, lum end end end if lum_bg > lum_fg then return (lum_bg + 0.05)/(lum_fg + 0.05) else return (lum_fg + 0.05)/(lum_bg + 0.05) end end function p.lum(frame) return color2lum(frame.args[1] or frame:getParent().args[1]) end function p.ratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._ratio(args) end function p.styleratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._styleratio(args) end function p.greatercontrast(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._greatercontrast(args) end return p cce580326bee8eaf3c81df6c76c04a9a2909dfa2 Модуль:Color contrast/colors 828 35 81 80 2025-01-31T15:24:07Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain return { aliceblue = 0.92880068253475, antiquewhite = 0.84646951707754, aqua = 0.7874, aquamarine = 0.8078549208338, azure = 0.97265264954166, beige = 0.8988459998705, bisque = 0.80732327372979, black = 0, blanchedalmond = 0.85084439608156, blue = 0.0722, blueviolet = 0.12622014321946, brown = 0.098224287876511, burlywood = 0.51559844533893, cadetblue = 0.29424681085422, chartreuse = 0.76032025902623, chocolate = 0.23898526114557, coral = 0.37017930872924, cornflowerblue = 0.30318641994179, cornsilk = 0.93562110372965, crimson = 0.16042199953026, cyan = 0.7874, darkblue = 0.018640801980939, darkcyan = 0.20329317839046, darkgoldenrod = 0.27264703559993, darkgray = 0.39675523072563, darkgreen = 0.091143429047575, darkgrey = 0.39675523072563, darkkhaki = 0.45747326349994, darkmagenta = 0.07353047651207, darkolivegreen = 0.12651920884889, darkorange = 0.40016167026524, darkorchid = 0.13413142174857, darkred = 0.054889674531132, darksalmon = 0.40541471563381, darkseagreen = 0.43789249325969, darkslateblue = 0.065792846227988, darkslategray = 0.067608151928044, darkslategrey = 0.067608151928044, darkturquoise = 0.4874606277449, darkviolet = 0.10999048339343, deeppink = 0.23866895828276, deepskyblue = 0.44481603395575, dimgray = 0.14126329114027, dimgrey = 0.14126329114027, dodgerblue = 0.27442536991456, firebrick = 0.10724525535015, floralwhite = 0.95922484825004, forestgreen = 0.18920812076002, fuchsia = 0.2848, gainsboro = 0.71569350050648, ghostwhite = 0.94311261886323, gold = 0.69860877428159, goldenrod = 0.41919977809569, gray = 0.2158605001139, green = 0.15438342968146, greenyellow = 0.80609472611453, grey = 0.2158605001139, honeydew = 0.96336535554782, hotpink = 0.34658438169715, indianred = 0.21406134963884, indigo = 0.03107561486337, ivory = 0.99071270600615, khaki = 0.77012343394121, lavender = 0.80318750514521, lavenderblush = 0.90172748631046, lawngreen = 0.73905893124963, lemonchiffon = 0.94038992245622, lightblue = 0.63709141280807, lightcoral = 0.35522120733135, lightcyan = 0.94587293494829, lightgoldenrodyellow = 0.93348351018297, lightgray = 0.65140563741982, lightgreen = 0.69091979956865, lightgrey = 0.65140563741982, lightpink = 0.58566152734898, lightsalmon = 0.4780675225206, lightseagreen = 0.35050145117042, lightskyblue = 0.56195637618331, lightslategray = 0.23830165007287, lightslategrey = 0.23830165007287, lightsteelblue = 0.53983888284666, lightyellow = 0.98161818392882, lime = 0.7152, limegreen = 0.44571042246098, linen = 0.88357340984379, magenta = 0.2848, maroon = 0.045891942324215, mediumaquamarine = 0.49389703310801, mediumblue = 0.044077780212328, mediumorchid = 0.21639251153773, mediumpurple = 0.22905858091648, mediumseagreen = 0.34393112338131, mediumslateblue = 0.20284629471622, mediumspringgreen = 0.70704308194184, mediumturquoise = 0.5133827926448, mediumvioletred = 0.14371899849357, midnightblue = 0.02071786635086, mintcream = 0.97834604947588, mistyrose = 0.82183047859185, moccasin = 0.80083000991567, navajowhite = 0.76519682342785, navy = 0.015585128108224, oldlace = 0.91900633405549, olive = 0.20027537200568, olivedrab = 0.22593150951929, orange = 0.4817026703631, orangered = 0.25516243753416, orchid = 0.31348806761439, palegoldenrod = 0.78792647887614, palegreen = 0.77936759006353, paleturquoise = 0.76436077921714, palevioletred = 0.28754994117889, papayawhip = 0.87797100199835, peachpuff = 0.74905589878251, peru = 0.30113074877936, pink = 0.63271070702466, plum = 0.45734221587969, powderblue = 0.68254586500605, purple = 0.061477070432439, rebeccapurple = 0.07492341159447, red = 0.2126, rosybrown = 0.32319457649407, royalblue = 0.16663210743188, saddlebrown = 0.097922285020521, salmon = 0.36977241527596, sandybrown = 0.46628543696283, seagreen = 0.19734199706275, seashell = 0.92737862206922, sienna = 0.13697631337098, silver = 0.52711512570581, skyblue = 0.55291668518184, slateblue = 0.14784278062136, slategray = 0.20896704076536, slategrey = 0.20896704076536, snow = 0.96533341834849, springgreen = 0.73052306068529, steelblue = 0.20562642207625, tan = 0.48237604163921, teal = 0.16996855778968, thistle = 0.56818401093733, tomato = 0.30638612719415, turquoise = 0.5895536427578, violet = 0.40315452986676, wheat = 0.74909702820482, white = 1, whitesmoke = 0.91309865179342, yellow = 0.9278, yellowgreen = 0.50762957208707, } 6ae47fdb24de4eed5ec26d203faf5341a388987b Шаблон:Yesno-yes 10 36 83 82 2025-01-31T15:24:07Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude> {{doc}} </noinclude> 3792ff694708f98102e3a6d556abe73bedc29069 Шаблон:Навигационная таблица 10 37 85 84 2025-01-31T15:24:09Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{#invoke:Navbox|navbox}}</includeonly>{{#ifeq: {{NAMESPACE}} | Шаблон | {{#switch: {{{1|{{{border|}}}}}} | child | subgroup | none = | {{#ifeq: {{{имя|{{{name|}}}}}} | {{PAGENAME}} | | {{#if:{{yesno|{{{tracking|}}}|no=1|yes=|blank=}} | | {{#if: {{{имя|{{{name|}}}}}} | {{#ifeq:{{ROOTPAGENAME}}|Работа недели||{{no-doc|[[Категория:Навигационные шаблоны, у которых нужно проверить параметр Имя]]}}}} | [[Категория:Навигационные шаблоны, у которых предположительно недостаёт параметра Имя]] }} }} }} }} }}<noinclude> {{doc}} </noinclude> b1c7f6e61d3b9cdd1daaf4d95e30e299a1d9eb5c Шаблон:No-doc 10 38 87 86 2025-01-31T15:24:09Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{#ifeq: {{SUBPAGENAME}} | doc || {{#if: {{#if: {{yesno|{{{nocat|}}}}} | x }}{{#switch: {{NAMESPACE}} | {{ns:10}} | {{ns:828}} = | x }} || {{{1|}}} }} }}<noinclude>{{doc}}</noinclude> da013ca5b5f97f94bee392ff3a4488046f2ceac7 Модуль:Separated entries 828 39 89 88 2025-01-31T15:24:10Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (convert to Unicode) HTML escape sequences, such as "&#32;" for space. and mw.text.decode(args.separator) or '' local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator -- Discard named parameters. local values = compressSparseArray(args) return mw.text.listToText(values, separator, conjunction) end local function makeInvokeFunction(separator, conjunction) return function (frame) local args = require('Module:Arguments').getArgs(frame) args.separator = separator or args.separator args.conjunction = conjunction or args.conjunction return p._main(args) end end p.main = makeInvokeFunction() p.br = makeInvokeFunction('<br />') p.newline = makeInvokeFunction('\n') p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain()) return p 33a68f0a46d62c42b6523a548f0f881e82ecfe58 Шаблон:T 10 40 91 90 2025-01-31T15:24:10Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Tl]] c0a76efe437d8a513d9f6878297f399a23944abd Шаблон:Tl 10 41 93 92 2025-01-31T15:24:11Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude> 61fe4d068895a5e7e5802767f5d7df71a7561c57 Шаблон:Str sub 10 42 95 94 2025-01-31T15:24:11Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude> {{doc}} </noinclude> 3043790f8803e868cf6097b475fd58ba742887fe Шаблон:Начало скрытого блока 10 43 97 96 2025-01-31T15:24:11Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!-- --><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!-- --><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!-- -->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!-- -->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!-- --><div class="mw-collapsible-toggle-placeholder"></div></div><!-- --><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!-- -->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!-- --></includeonly><noinclude> {{doc}} </noinclude> 3b96bb802b522e629c41cddc5d44dfb2a9eb462a Шаблон:Скрытый блок/styles.css 10 44 99 98 2025-01-31T15:24:11Z Генерал Альдации 2 1 версия импортирована text text/plain .ts-Скрытый_блок { margin: 0; overflow: hidden; border-collapse: collapse; box-sizing: border-box; } .ts-Скрытый_блок-title { text-align: center; font-weight: bold; line-height: 1.6em; min-height: 1.2em; } .ts-Скрытый_блок .mw-collapsible-content { overflow-x: auto; overflow-y: hidden; clear: both; } .ts-Скрытый_блок::before, .ts-Скрытый_блок .mw-collapsible-toggle { padding-top: .1em; width: 6em; font-weight: normal; font-size: calc(90% / 0.95); } .ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { float: right; text-align: right; } .ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { float: left; text-align: left; } .ts-Скрытый_блок-gray { padding: 2px; border: 1px solid var(--border-color-base, #a2a9b1); } .ts-Скрытый_блок-transparent { border: none; } .ts-Скрытый_блок-gray .ts-Скрытый_блок-title { background: var(--background-color-neutral, #eaecf0); padding: .1em 6em; padding-right: 0; } .ts-Скрытый_блок-transparent .ts-Скрытый_блок-title { background: transparent; padding: .1em 5.5em; padding-right: 0; } .ts-Скрытый_блок-gray .mw-collapsible-content { padding: .25em 1em; } .ts-Скрытый_блок-transparent .mw-collapsible-content { padding: .25em 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { padding-right: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { padding-right: 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { padding-left: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { padding-left: 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 1em; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 6.5em; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle { padding-right: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-rightTitle, .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 0; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle, .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle { padding-right: 0; } .ts-Скрытый_блок + .ts-Скрытый_блок, .ts-Скрытый_блок + link + .ts-Скрытый_блок { border-top-style: hidden; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ b04b4e8d09f2a95b9b1ca08e8c10ef52169ec7f1 Шаблон:Ifempty 10 45 101 100 2025-01-31T15:24:11Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{#invoke:Ifempty|main}}</includeonly><noinclude> {{Doc}} <!-- Add categories and interwikis to the /doc subpage, not here! Добавляйте категории и интервики на подстраницу документации, а не сюда --> </noinclude> c14bef2160201468f96da309e565ff2fde725cf5 Шаблон:Конец скрытого блока 10 46 103 102 2025-01-31T15:24:12Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly></div></div></includeonly><noinclude> {{doc|Шаблон:Начало скрытого блока/doc}}</noinclude> 2da6ac8eb0812fb4183a70b516009d40920e281f Шаблон:Str len 10 47 105 104 2025-01-31T15:24:12Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 95f10258d5214440d2706952656564f216c2e4cc Модуль:Ifempty 828 48 107 106 2025-01-31T15:24:12Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local p = {} local getArgs = require('Module:Arguments').getArgs function p.main(frame) local args = getArgs(frame, {removeBlanks = false}) local before = args['до'] local after = args['после'] for i, v in ipairs(args) do if v ~= '' then return (before or '') .. v .. (after or '') end end end return p 875e8c9f03fb4cc02d80271ad3aaab13a9bcea86 Шаблон:Str rightc 10 49 109 108 2025-01-31T15:24:13Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude> 0401d500dcc2224d44867ba0ea1f6c0fbeb758a0 Модуль:Hash 828 50 111 110 2025-01-31T15:24:13Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local p = {} local function inTable(table, value) for k, v in pairs(table) do if v == value then return true end end return false end function p.list(frame) return table.concat(mw.hash.listAlgorithms(), '; ') end function p.main(frame) local args = getArgs(frame, { frameOnly = true }) local algorithm if not args[1] then return '<span class="error">Не указана строка для хеширования.</span>' end if args[2] then if not inTable(mw.hash.listAlgorithms(), args[2]) then return '<span class="error">Алгоритм хеширования ' .. args[2] .. ' не поддерживается, или вы неточно указали его имя. Используйте функцию <kbd>mw.hash.listAlgorithms()</kbd> для получения списка доступных алгоритмов.</span>' end algorithm = args[2] else -- Алгоритм выбран из соображений быстродействия (см. [[:en:Fowler–Noll–Vo hash function]]), -- 64-битная функция используется для уменьшения вероятности коллизий до пренебрежимо малой -- величины. Возможно, есть лучшая опция — проверяйте. algorithm = 'fnv164' end return mw.hash.hashValue(algorithm, args[1]) end return p 5d18513e574435f191164695449a620b031f93ec Шаблон:Скрытый блок 10 51 113 112 2025-01-31T15:24:13Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{Начало скрытого блока |id = {{{id|}}} |тип = {{{тип|{{{type|}}}}}} |состояние = {{{state|{{{состояние|collapsed}}}}}} |класс_тела = {{{класс_тела|{{{класс тела|}}}}}} |стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}} |рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}} |ссылка = {{{Ссылка|{{{ссылка|}}}}}} |класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}} |шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}} |класс_текста = {{{класс_текста|{{{класс текста|}}}}}} |шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}} {{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}} {{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }} {{Конец скрытого блока}}<noinclude> {{doc}} </noinclude> 792dc9fb2eb659877e2e758f4ce405e1d3f8352b Шаблон:Tlp 10 52 115 114 2025-01-31T15:24:13Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude> 36c309cb28ccf0901f4fff46cbd35cdabcf00661 Шаблон:Doc 10 53 117 116 2025-01-31T15:24:14Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}} {{#if: {{{1|}}} | {{#ifexist: {{#if: {{NAMESPACE:{{{1}}}}} | {{{1}}} | {{SUBJECTSPACE}}:{{{1}}} }} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{#ifexist: {{SUBJECTSPACE}}:{{{1}}} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{Документировать|{{{1}}}}} }} }} | {{#ifexist: {{SUBJECTPAGENAME}}/doc | {{{{SUBJECTPAGENAME}}/doc}} | {{Документировать|{{SUBJECTPAGENAME}}/doc}} }} }} {{doc/end}}</includeonly><noinclude> {{doc}} </noinclude> 7298506ab2882f16fe7a52e0e080b2780b237bb9 Шаблон:Doc/begin 10 54 119 118 2025-01-31T15:24:14Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Doc/styles.css" /> <div class="ts-doc-doc" id="doc"> <div class="ts-doc-header" id="Документация"> <div class="ts-doc-heading">Документация</div> {{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }} </div> <div class="ts-doc-content"></includeonly><noinclude> {{doc}} </noinclude> c753f0a9f65d86707cdffaf93fb49c2c52daf92b Шаблон:Doc/styles.css 10 55 121 120 2025-01-31T15:24:14Z Генерал Альдации 2 1 версия импортирована text text/plain .ts-doc-doc { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); clear: both; margin-top: 1em; } /* Ctrl+F ":target" in [[MediaWiki:Common.css]] */ .ts-doc-doc sup.reference:target, .ts-doc-doc ol.references li:target, .ts-doc-doc .highlight-target:target, .ts-doc-doc cite:target, .ts-doc-doc span.citation:target { background: var(--ruwiki-background-color-blue200, #cfe3ff); } .ts-doc-header { align-items: center; background: var(--ruwiki-background-color-blue200, #cfe3ff); display: flex; flex-wrap: wrap; padding: .642857em 1em .5em; overflow: hidden; } .ts-doc-header .ts-tlinks-tlinks { margin-left: auto; } .ts-doc-content { padding: .214286em 1em; } .ts-doc-content:after { content: ''; clear: both; display: block; } .ts-doc-heading { display: inline-block; padding-left: 2em; background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat; background-size: contain; font-size: small; min-height: 1.75em; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; } @media screen { html.skin-theme-clientpref-night .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } .ts-doc-content > *:first-child, .ts-doc-footer > *:first-child { margin-top: .5em; } .ts-doc-content > *:last-child, .ts-doc-footer > *:last-child { margin-bottom: .5em; } .ts-doc-footer { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); padding: .214286em 1em; margin-top: .214286em; margin-bottom: .214286em; font-style: italic; } @media (max-width: 719px) { .ts-doc-header { display: block; } .ts-doc-header .ts-tlinks-tlinks { float: none; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ be8d912472a37a6051bee114da86f913839e7ca0 Шаблон:Действия для страницы 10 56 123 122 2025-01-31T15:24:14Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!-- -->{{join|separator=<span class="mw-editsection-divider"> &amp;#124; </span> |1={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }} }} |2={{#ifexist: {{#rel2abs: {{{lc|}}} }} | [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]] }} |3={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }} }} |4={{#ifexist: {{#rel2abs: {{{lc|}}} }} | | [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать] }} |5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }} |6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }} }}<span class="mw-editsection-bracket">]</span></div><noinclude> {{doc}} </noinclude> 9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4 Шаблон:Действия для страницы/styles.css 10 57 125 124 2025-01-31T15:24:15Z Генерал Альдации 2 1 версия импортирована text text/plain .ts-tlinks-tlinks { font-weight: normal; float: right; line-height: inherit; } .ts-tlinks-tlinks .mw-editsection-divider { display: inline; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ a003e896d263c29e66d2246b210e5d73e577ea46 Шаблон:Doc/end 10 58 127 126 2025-01-31T15:24:15Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly></div> </div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] --> | {{^|1em}} | <div class="ts-doc-footer plainlinks"> {{#ifeq: {{str left|{{PAGENAME}}|9}} | Песочница | | {{#ifeq: {{str rightc|{{PAGENAME}}|10}} | /песочница | | Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}} | Модуль | модуль | шаблон }}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }} | {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }} }})</small> или {{#ifeq: {{NAMESPACE}} | Модуль | [[Модуль:Песочница|песочнице для модулей]] | своём [[ВП:ЛП|личном пространстве]] }}.<br> }} }}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]].&#32;}}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]. </div> }}</includeonly><noinclude>{{doc}}</noinclude> 758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e Шаблон:Ombox 10 59 129 128 2025-01-31T15:24:15Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{#invoke:Message box|ombox}}<noinclude> {{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude> ab34435c5ebc29de589c9b059e88da5d0e6f16e4 Шаблон:Docpage 10 60 131 130 2025-01-31T15:24:16Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{#ifeq: {{SUBPAGENAME}} | doc | {{fmbox | class = hlist nowraplinks | style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff); | image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]] | text = <div> * [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]] * [[:{{SUBJECTPAGENAME}}|Документация]] * [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]] * [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} | ** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}} }}</div><!-- -->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }} }}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}} | Модуль | [[Категория:Модули:Документация]] | [[Категория:Шаблоны:Документация]] }}__EXPECTED_UNCONNECTED_PAGE__ }} }}</includeonly><noinclude>{{doc}}</noinclude> e2d07566c50be35ac409e8396893a3b9d8676e0c Шаблон:Очистить кэш 10 61 133 132 2025-01-31T15:24:16Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <!-- Класс purgelink и атрибут data-pagename используются в [[MediaWiki:Common.js]], чтобы очищать кэш без перехода на отдельную страницу --><span class="noprint purgelink" {{#if: {{{2|}}} | data-pagename="{{{2}}}" }}>{{выполнить скрипт|purgeLink}}[[Special:Purge/{{#if: {{{2|}}} | {{{2}}} | {{FULLPAGENAME}} }}|{{#if: {{{1|}}} | {{{1}}} | Очистить кэш }}]]</span>{{#ifeq: {{NAMESPACE}}{{{nocat|}}} | {{ns:10}} <!-- Шаблон --> | {{очищать кэш|ежедневно}} }}<noinclude>{{doc}}</noinclude> be6695060ca61d2125386d02d3a19109c0e7c27b Шаблон:Скрытый 10 62 135 134 2025-01-31T15:24:16Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Скрытый блок]] 97cc939c1c8ece875b2ec360f85980bd6f1bbed7 Модуль:Navbar 828 63 137 136 2025-01-31T15:24:17Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local p = {} local hlist = 'Template:Flatlist/styles.css' local templatestyles = 'Module:Navbar/styles.css' local getArgs function p._ruwikiNavbar( args ) local titleText = args[ 1 ] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local title = mw.title.new(mw.text.trim(titleText), 'Template'); if not title then error('Invalid title ' .. titleText) end local whiteColorDefs = { ['#fff'] = true, ['#ffffff'] = true, ['white'] = true, } local fontColor = args.fontcolor and args.fontcolor:lower() local isWhite = fontColor and whiteColorDefs[ fontColor ] == true local fontStyle = args.fontstyle and mw.text.unstripNoWiki( args.fontstyle:lower() ) if not isWhite and fontStyle then local styleratio = require( 'Module:Color contrast' )._styleratio isWhite = styleratio( { fontStyle .. '; color:#666;', '', '#666' } ) < 3.66 end local isTemplate = title.namespace == 10 local altText = string.format( 'Перейти %s «%s»', isTemplate and 'к шаблону' or 'на страницу', mw.text.split( isTemplate and title.text or title.fullText, '#' )[ 1 ] ) return string.format( '[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|class=noprint%s|link=%s|%s]]', isWhite and ' white' or '', isWhite and '' or ' skin-invert-image', tostring( title ), altText ) end function p.ruwikiNavbar(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._ruwikiNavbar(getArgs(frame)) end function p._navbar(args) local titleArg = 1 if args.collapsible then titleArg = 2 if not args.plain then args.mini = 1 end if args.fontcolor then args.fontstyle = 'color:' .. args.fontcolor .. ';' end args.style = 'float:left; text-align:left; white-space:nowrap;' end if args[titleArg] == 'off' then return end local titleText = args[titleArg] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local title = mw.title.new(mw.text.trim(titleText), 'Template'); if not title then error('Invalid title ' .. titleText) end local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or ''; local tag if args.nodiv then tag = 'span' else tag = 'div' end local div = mw.html.create():tag(tag) div :addClass('navbar hlist plainlinks noprint') :attr('data-navboxnavigation-link', '0') :cssText(args.style) if args.mini then div:addClass('navbar-mini') end if not (args.mini or args.plain) then div :tag('span') :addClass('navbar-boxtext') :cssText(args.fontstyle) :wikitext(args.text or 'Шаблон:') :wikitext(' ') end local ul = div:tag('ul'); if args.brackets then ul:addClass('navbar-brackets') end ul :tag('li') :addClass('nv-view') :wikitext('[[' .. title.fullText .. '|') :tag(args.mini and 'abbr' or 'span') :addClass(args.mini and 'navbar-mini-abbr') :attr('title', 'Просмотр этого шаблона') :cssText(args.fontstyle) :wikitext(args.mini and 'п' or 'просмотр') :done() :wikitext(']]') :done() :tag('li') :addClass('nv-talk') :wikitext('[[' .. talkpage .. '|') :tag(args.mini and 'abbr' or 'span') :attr('title', 'Обсуждение этого шаблона') :cssText(args.fontstyle) :wikitext(args.mini and 'о' or 'обсуждение') :done() :wikitext(']]'); if not args.noedit then ul :tag('li') :addClass('nv-edit') :wikitext('[[Special:EditPage/' .. title.fullText .. '|') :tag(args.mini and 'abbr' or 'span') :attr('title', 'Править этот шаблон') :cssText(args.fontstyle) :wikitext(args.mini and 'р' or 'править') :done() :wikitext(']]'); end if args.collapsible then div:done() :tag('span') :addClass( args.mini and 'navbar-ct-mini' or 'navbar-ct-full' ) :cssText(args.fontstyle) :wikitext(args[1]) end local frame = mw.getCurrentFrame() return frame:extensionTag{ name = 'templatestyles', args = { src = hlist } } .. frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles } } .. tostring(div:done()) end function p.navbar(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._navbar(getArgs(frame)) end return p 695777e4dafbd5f7bf8b4f35d8db9349d08a363d Шаблон:OnLua 10 64 139 138 2025-01-31T15:24:17Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Lua]] b72371e7ae22239863c474a78238171c2bd94c7e Шаблон:Tnav 10 65 141 140 2025-01-31T15:24:17Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{t|{{{1|}}}|nav|comment={{{comment|}}}}}<noinclude> {{doc-inline}} Это — обёртка для шаблона {{t|tl}}, предназначенная для использования в блоках навигации. Она передаёт в него флаг <code>nav</code> и комментарий в параметре {{para|comment}}. {{шаблоны для документирования}} {{doc-end}} [[Категория:Шаблоны:Ссылки на шаблоны]] [[Категория:Шаблоны:Для навигационных шаблонов]] </noinclude> 583d607aa213790ae32dda4018a413255493e42b Шаблон:Выполнить скрипт 10 66 143 142 2025-01-31T15:24:17Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{#switch: {{{1|}}} | = | mainPage = [[Категория:Википедия:Заглавная страница|{{NAMESPACENUMBER}}]] | #default = {{#ifexist: Категория:Википедия:Страницы с гаджетом по требованию {{{1}}} | [[Категория:Википедия:Страницы с гаджетом по требованию {{{1}}}|{{NAMESPACENUMBER}}]] }} }}<noinclude> {{doc}} </noinclude> 6979ea0342067dc76b9adcb9a5e072207c2c5a63 Шаблон:OnLua/Строка 10 67 145 144 2025-01-31T15:24:18Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Lua/Строка]] d7f869ccc7a7efc800399fce32bc75e0f91066de Шаблон:Дерево категорий 10 68 147 146 2025-01-31T15:24:18Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <div>{{{title|'''Дерево категорий'''}}} {{#tag: categorytree| {{#if:{{{1|}}}|{{{1}}}|{{PAGENAME}}}} | mode = {{#if:{{{2}}}|"{{#ifeq:{{{2}}}|всё|all|{{#ifeq:{{{2}}}|страницы|pages|{{#ifeq:{{{2}}}|категории|categories|{{{2}}}}}}}}}"}} | depth = {{#if:{{{3}}}|{{{3}}}}} }} </div><noinclude> {{doc}} </noinclude> 9763d532ff7b79a638abe485875db984254b57db Шаблон:СИШ 10 69 149 148 2025-01-31T15:24:18Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <noinclude>{{к объединению|2020-11-10|Шаблон:High-use}} </noinclude>{{ombox |type = notice |image = [[Файл:Stalewarning.svg|40px|alt=Время]] |text = '''Внимание! Это один из [[Special:MostLinkedTemplates|самых используемых {{#ifeq: {{NAMESPACENUMBER}} | 828 | модулей | шаблонов }}]].''' |text-small = Каждое его изменение создаёт [[mw:Manual:Job queue/ru|дополнительную нагрузку]] на сервера проекта. Пожалуйста, убедитесь в адекватности и правильности ваших изменений, проверьте их на тестовых страницах.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений]. }}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Шаблоны:С более чем 100 тысячами использований]]}}</includeonly><noinclude> {{doc}} </noinclude> 013201ef8d4ba8e3d1eb0dbba9c331a3d4ae519b Шаблон:Подстраницы шаблона Карточка 10 70 151 150 2025-01-31T15:24:19Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{Навигационная таблица |имя = Подстраницы шаблона Карточка |state = {{{state|}}} |класс_списков = hlist hlist-items-nowrap |заголовок = Подстраницы шаблона {{tnav|Карточка}} |tracking = <includeonly>no</includeonly> |группа1 = {{!}}вверху= |список1 = * {{tnav|карточка/название}} (заголовок без уточнения) * {{tnav|карточка/имя}} (заголовок в обратном порядке и без уточнения) |группа2 = {{!}}вверху2= |список2 = * {{tnav|карточка/оригинал названия}} (свойство [[d:P:P1705|P1705]]) * {{tnav|карточка/оригинал названия произведения}} (свойство [[d:P:P1476|P1476]]) * {{tnav|карточка/официальное название}} (свойство [[d:P:P1448|P1448]]) * {{tnav|карточка/оригинал имени}} (свойство [[d:P:P1559|P1559]]) |группа3 = Разное |список3 = * {{tnav|карточка/изображение}} * {{tnav|карточка/Изображение рядом}} * {{tnav|карточка/флаг и герб}} (свойства [[d:p:P41|P41]] и [[d:p:P94|P94]]) * {{tnav|карточка/медали}} (свойство [[d:p:P166|P166]]) * {{tnav|карточка/хронология}} (свойства [[d:p:P155|P155]] и [[d:p:P156|P156]]) * {{tnav|карточка/период}} (свойства [[d:p:P580|P580]] и [[d:p:P582|P582]]) * {{tnav|карточка/коды в каталогах}} (свойство [[d:p:P528|P528]]) * {{tnav|карточка/блок}} * {{tnav|карточка/блок с маркерами}} |группа4 = {{!}}внизу= |список4 = * {{tnav|карточка/Викигид}} * {{tnav|карточка/Викиданные}} * {{tnav|карточка/Викисклад}} (свойство [[d:P:P373|P373]]) * {{tnav|карточка/Викитека}} * {{tnav|карточка/Викиучебник}} * {{tnav|карточка/Викицитатник}} |класс_внизу = hlist |внизу = ; См. также : [[Википедия:Шаблоны-карточки]] : [[:Категория:Шаблоны:Для шаблонов-карточек]] }}<noinclude> [[Категория:Навигационные шаблоны:Для шаблонов]] </noinclude> 3fd4b54a761d9de6d7ddaac86889f4abf8478d95 Шаблон:Lua 10 71 153 152 2025-01-31T15:24:19Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{ombox | small = yes | style = width:23em; | image = [[Файл:Lua-logo-nolabel.svg|40px|alt=|link=]] | text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|&#58;<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}|&#32;с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из&#32;}}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!-- -->{{#invoke:Transclude|npc|OnLua/Строка| module= |function= |tech= |line= }}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}} }}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}</noinclude> f1fdaa87edb15d61e23e98f6e25d171a975e10eb Шаблон:Карточка/doc 10 72 155 154 2025-01-31T15:24:20Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{docpage}} {{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}} {{СИШ}} Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]]. == Параметры == === Служебные === ; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>. ; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да». ; from: Указывается элемент Викиданных, из которого берётся информация. === Основные === ; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи. ; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия. ; вверху3: Дополнительный текст, отображаемый вверху таблицы. ; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>. ; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется. ; изображение2: Дополнительное изображение. ; изображение3: Дополнительное изображение. ; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1. ; метка<sub>n</sub>: Используется для подписи текста ; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках. ; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в &#60;tr&#62;, таких как {{t|карточка/блок}}. ; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто. Для вариантов форматирования значений, см. документацию [[Модуль:WikidataSelectors]]. ; внизу ; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом). === Стили === ; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}} ; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code> ; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code> ; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code> ; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание ; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение ; стиль_подписи: Применяется к подписи изображения ; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code> ; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n ; стиль_меток: Применяется к меткам ; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n ; стиль_текста: Применяется к тексту ; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n ; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''. ; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам. == Возможности == === Сдвоенные ячейки === Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код: <pre><nowiki> |текст2 = {{{параметр|}}} |стиль_текста2 = text-align:left; </nowiki></pre> === Необязательные ячейки === Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом: <pre><nowiki> |метка5 = Население |текст5 = {{{население|}}} </nowiki></pre> Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена. === Необязательные заголовки === Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>: <pre><nowiki> |заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}} |метка6 = Содержимое |текст6 = {{{содержимое|}}} |метка7 = Размещение |текст7 = {{{размещение|}}} </nowiki></pre> Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN. {| |- |<pre><nowiki> |заголовок1 = {{{заголовок1|}}} |метка1 = {{{метка1|}}} |текст1 = {{{текст1|}}} </nowiki></pre> |} {| |- |<pre><nowiki> |заголовок1 = заголовок_текст |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- ! заголовок_текст |} |<pre><nowiki> |заголовок1 = |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- | метка_текст|| текст_текст |} |} === Оформление параметров === Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён: <pre><nowiki> |метка6 = Масса |текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}} </nowiki></pre> А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например: <pre><nowiki> |метка6 = Раса |текст6 = {{#switch:{{{раса|}}} |Европеоиды = [[Европеоидная раса|Европеоиды]] |Негроиды = [[Негроидная раса|Негроиды]] |Монголоиды = [[Монголоидная раса|Монголоиды]] |{{{раса|}}} }} </nowiki></pre> == Пустой шаблон == <pre> {{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = |вверху2 = |изображение = |заголовок1 = |метка2 = |текст2 = |викиданные2 = |метка3 = |текст3 = |викиданные3 = |метка4 = |текст4 = |викиданные4 = |метка5 = |текст5 = |викиданные5 = |метка6 = |текст6 = |викиданные6 = |метка7 = |текст7 = |викиданные7 = |метка8 = |текст8 = |викиданные8 = |метка9 = |текст9 = |викиданные9 = |метка10 = |текст10 = |викиданные10 = ... |меткаN = |текстN = |викиданныеN = |внизу = }}<noinclude> {{doc}} </noinclude></pre> {{скрытый|Заголовок=11—20|Содержание=<pre> |метка11 = |текст11 = |викиданные11 = |метка12 = |текст12 = |викиданные12 = |метка13 = |текст13 = |викиданные13 = |метка14 = |текст14 = |викиданные14 = |метка15 = |текст15 = |викиданные15 = |метка16 = |текст16 = |викиданные16 = |метка17 = |текст17 = |викиданные17 = |метка18 = |текст18 = |викиданные18 = |метка19 = |текст19 = |викиданные19 = |метка20 = |текст20 = |викиданные20 = </pre>}} {{скрытый||Заголовок=21—30|Содержание=<pre> |метка21 = |текст21 = |викиданные21 = |метка22 = |текст22 = |викиданные22 = |метка23 = |текст23 = |викиданные23 = |метка24 = |текст24 = |викиданные24 = |метка25 = |текст25 = |викиданные25 = |метка26 = |текст26 = |викиданные26 = |метка27 = |текст27 = |викиданные27 = |метка28 = |текст28 = |викиданные28 = |метка29 = |текст29 = |викиданные29 = |метка30 = |текст30 = |викиданные30 = </pre>}} {{скрытый||Заголовок=31—40|Содержание=<pre> |метка31 = |текст31 = |викиданные31 = |метка32 = |текст32 = |викиданные32 = |метка33 = |текст33 = |викиданные33 = |метка34 = |текст34 = |викиданные34 = |метка35 = |текст35 = |викиданные35 = |метка36 = |текст36 = |викиданные36 = |метка37 = |текст37 = |викиданные37 = |метка38 = |текст38 = |викиданные38 = |метка39 = |текст39 = |викиданные39 = |метка40 = |текст40 = |викиданные40 = </pre>}} {{скрытый||Заголовок=41—50|Содержание=<pre> |метка41 = |текст41 = |викиданные41 = |метка42 = |текст42 = |викиданные42 = |метка43 = |текст43 = |викиданные43 = |метка44 = |текст44 = |викиданные44 = |метка45 = |текст45 = |викиданные45 = |метка46 = |текст46 = |викиданные46 = |метка47 = |текст47 = |викиданные47 = |метка48 = |текст48 = |викиданные48 = |метка49 = |текст49 = |викиданные49 = |метка50 = |текст50 = |викиданные50 = </pre>}} {{скрытый||Заголовок=51—60|Содержание=<pre> |метка51 = |текст51 = |викиданные51 = |метка52 = |текст52 = |викиданные52 = |метка53 = |текст53 = |викиданные53 = |метка54 = |текст54 = |викиданные54 = |метка55 = |текст55 = |викиданные55 = |метка56 = |текст56 = |викиданные56 = |метка57 = |текст57 = |викиданные57 = |метка58 = |текст58 = |викиданные58 = |метка59 = |текст59 = |викиданные59 = |метка60 = |текст60 = |викиданные60 = </pre>}} == Примерный шаблон для карточки персоны == <pre>{{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = {{карточка/имя|{{{имя|}}}}} |вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}} |изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}} |метка1 = Имя при рождении |текст1 = {{{имя при рождении|}}} |викиданные1 = p1477 |метка2 = Дата рождения |текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}} |метка3 = Место рождения |текст3 = {{{место рождения|}}} |викиданные3 = p19 |метка4 = Дата смерти |текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}} |метка5 = Место смерти |текст5 = {{{место смерти|}}} |викиданные5 = p20 |метка6 = Гражданство |текст6 = {{{гражданство|}}} |викиданные6 = p27 |метка7 = Сценические имена / Прозвище |текст7 = {{{прозвище|}}} |викиданные7 = p1449 |заголовок8 = {{wikidata|p856|{{{сайт|}}}}} |внизу = {{карточка/Викисклад|{{{викисклад|}}}}} }}</pre> Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом: * <code>13.05.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]]; * <code>12.06.1801 (31.05)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]]; * <code>12.01.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]). == Отслеживающие категории, подставляемые шаблоном == {{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}} == См. также == * [[Википедия:Шаблоны-карточки]] * {{t|Универсальная карточка}} * {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке) * [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]] * [[Участник:Jack who built the house/alignTemplateParameters.js]] {{Подстраницы шаблона Карточка}} <includeonly> [[Категория:Шаблоны-карточки|*]] [[Категория:Шаблоны:Мета-шаблоны]] </includeonly> 29badbe2200149ba091573e4e4e11106d20e0688 Модуль:Message box/ombox.css 828 73 157 156 2025-01-31T15:24:20Z Генерал Альдации 2 1 версия импортирована text text/plain /* Скопировано из [[:en:Module:Message box/ombox.css]] */ .ombox { margin: 4px 0; border-collapse: collapse; border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */ background-color: var(--background-color-neutral-subtle, #f8f9fa); box-sizing: border-box; } /* For the "small=yes" option. */ .ombox.mbox-small { font-size: 88%; line-height: 1.25em; } .ombox-speedy { border: 2px solid var(--border-color-error, #b32424); /* Red */ background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */ } .ombox-delete { border: 2px solid var(--background-color-error--active, #b32424); /* Red */ } .ombox-content { border: 1px solid #f28500; /* Orange */ } .ombox-style { border: 1px solid #fc3; /* Yellow */ } .ombox-move { border: 1px solid #9932cc; /* Purple */ } .ombox-protection { border: 2px solid var(--border-color-base, #a2a9b1); /* Gray-gold */ } .ombox .mbox-text { border: none; /* @noflip */ padding: 0.25em 0.9em; width: 100%; } .ombox .mbox-image { border: none; /* @noflip */ padding: 2px 0 2px 0.9em; text-align: center; } .ombox .mbox-imageright { border: none; /* @noflip */ padding: 2px 0.9em 2px 0; text-align: center; } /* An empty narrow cell */ .ombox .mbox-empty-cell { border: none; padding: 0; width: 1px; } .ombox .mbox-invalid-type { text-align: center; } /* Хак, TODO: посмотреть, как оно на самом деле работает */ .ombox .mbox-textsmall-div { font-size: 90%; } @media (min-width: 720px) { .ombox { margin: 4px 10%; } .ombox.mbox-small { /* @noflip */ clear: right; /* @noflip */ float: right; /* @noflip */ margin: 4px 0 4px 1em; width: 238px; } /* Стили нотификаций для ноутбуков */ @media (max-width: 1366px) { .ombox { margin-left: 6%; margin-right: 6%; } } } /* [[Категория:Модули:Подстраницы CSS]] */ 6627874170f6674674bfa5796b2f7dfb6698cd81 Шаблон:Lua/Строка 10 74 159 158 2025-01-31T15:24:21Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{#if: {{{module|}}}{{{tech|}}} | <li>с использованием {{#if: {{{tech|}}} | {{{tech}}} | {{#if: {{{function|}}} | {{#if: {{{module|}}} | функции <code>{{#if: {{{line|}}} | [{{fullurl: Module:{{{module}}}|action=edit}}#mw-ce-l{{{line}}} {{{function}}}()] | [[{{{funcref|Module:{{{module}}}#{{{function}}}}}} | {{{function}}}()]]}}</code> из&#32;}}}}{{#if: {{{module|}}} | модуля [[Module:{{{module}}} | {{{module}}}]]}}}};}}</includeonly><noinclude>[[Категория:Шаблоны:Подстраницы шаблонов]]</noinclude> 5a35837338c2daee2d240a8e5335e8fec8e7d87e Шаблон:Langi 10 75 161 160 2025-01-31T15:24:21Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <span lang="{{{1}}}" xml:lang="{{{1}}}" style="font-style:italic;">{{{2}}}</span><noinclude>{{doc}}</noinclude> 7bb9f9098c88e770b982402adf30a3bbf645aa4b Шаблон:Карточка/название 10 76 163 162 2025-01-31T15:24:21Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{#if:{{{1|}}}|{{{1}}}|{{без уточнения|{{PAGENAME}}}}}}<noinclude> {{doc}} </noinclude> 110edc6d8286f120a048863c68371720bd4e65ca Шаблон:Без уточнения 10 77 165 164 2025-01-31T15:24:21Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{ {{{|safesubst:}}}#invoke:String|replace|{{{1|{{ {{{|safesubst:}}}PAGENAME}}}}}|^%s*(.+)%s+%b()%s*$|%1||false}}</includeonly><noinclude>{{doc}}</noinclude> 1fcb3edb0be49656ae0f913e9a8fb4853264b480 Шаблон:Wikidata 10 78 167 166 2025-01-31T15:24:22Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{#invoke:Wikidata|formatProperty|property={{{1|}}}|value={{{2|}}}}}</includeonly><noinclude>{{doc}}</noinclude> 9d3d422eca39504b018df6ec0bb047392a7aba7e Шаблон:Wikidata number switch 10 79 169 168 2025-01-31T15:24:22Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{#if: {{{3|}}} | {{#if: {{{5|}}} | {{{5|}}} | {{{3|}}} }} | {{#if: {{{2|}}} | {{#if: {{{4|}}} | {{{4|}}} | {{{2|}}} }} | {{#if: {{{1|}}} | {{#if: {{{4|}}}{{{5|}}} | {{#if: {{wikidata|{{{1|}}}|property-module=Wikidata/count|property-function=isMultiple|from={{{from|}}}}} | {{{5|}}} | {{{4|}}} }} | {{wikidata|{{{1|}}}|from={{{from|}}}}} }} }} }} }}<noinclude> {{doc}} </noinclude> 7541bb47e73905a8ee240baa1dab1801f9f7b166 Шаблон:Карточка/Викисклад 10 80 171 170 2025-01-31T15:24:22Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{wikidata|p373|{{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}}|plain=false|text=Медиафайлы на Викискладе|icon={{{icon|}}}|icon_size={{{icon_size|}}}|from={{{from|}}}}}<!-- -->{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#if: {{{1|}}} | [[Категория:Википедия:Ссылка на Викисклад непосредственно в статье]]<!-- -->{{#if: {{wikidata|p373|plain=true}} | {{#ifeq: {{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}} | {{wikidata|p373|plain=true}} |[[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных совпадают]]| [[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных отличаются]] }} | [[Категория:Википедия:Ссылка на Викисклад в статье, но не на Викиданных]] }} }}<!-- --> }}<!-- -->{{#ifeq: {{NAMESPACE}} | Шаблон | {{#if: {{{2|}}} | [[Категория:Википедия:Шаблоны для низа карточек с лишним параметром]] }} }}<!-- --><noinclude> {{doc}} </noinclude> 40ef9a463c772ddbf54feae9e21d4037b692253e Шаблон:Str rep 10 81 173 172 2025-01-31T15:24:23Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|{{{4|1}}}}}</includeonly><noinclude>{{doc}}</noinclude> c75032f150c372324c69a6f62ff4ab1492ad4cfa Модуль:Wikidata 828 82 175 174 2025-01-31T15:24:23Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain ---settings, may differ from project to project local fileDefaultSize = '267x400px' local outputReferences = true local writingSystemElementId = 'Q8209' local langElementId = 'Q7737' ---Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании) local moduleSources = require( 'Module:Sources' ) local WDS = require( 'Module:WikidataSelectors' ) ---Константы ---@type string local CONTENT_LANGUAGE_CODE = mw.language.getContentLanguage():getCode() local p = {} local g_config, g_frame local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement, formatStatementDefault, getSourcingCircumstances, getPropertyParams ---@param obj table ---@param target table ---@param skipEmpty boolean | nil ---@return table local function copyTo( obj, target, skipEmpty ) for key, val in pairs( obj ) do if skipEmpty ~= true or ( val ~= nil and val ~= '' ) then target[ key ] = val end end return target end ---@param prev number | nil ---@param next number | nil ---@return number | nil local function min( prev, next ) if prev == nil or prev > next then return next end return prev end ---@param prev number | nil ---@param next number | nil ---@return number | nil local function max( prev, next ) if prev == nil or prev < next then return next end return prev end ---@param section string ---@param code string ---@return any | nil local function getConfig( section, code ) if g_config == nil then g_config = require( 'Module:Wikidata/config' ) end if not g_config then g_config = {} end if not section then return g_config end if not code then return g_config[ section ] or {} end if not g_config[ section ] then return nil end return g_config[ section ][ code ] end ---@param code string ---@param sortKey string | nil ---@return string local function getCategoryByCode( code, sortKey ) local value = getConfig( 'categories', code ) if not value or value == '' then return '' end if sortKey ~= nil then return '[[Category:' .. value .. '|' .. sortKey .. ']]'; -- экранировать? else return '[[Category:' .. value .. ']]' end end ---@param isoStr string | table ---@return table | nil local function splitISO8601( isoStr ) if 'table' == type( isoStr ) then if isoStr.args and isoStr.args[ 1 ] then isoStr = '' .. isoStr.args[ 1 ] else return 'unknown argument type: ' .. type( isoStr ) .. ': ' .. table.tostring( isoStr ) end end local Y, M, D = ( function( str ) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local _Y, _M, _D = mw.ustring.match( str, pattern ) return tonumber( _Y ), tonumber( _M ), tonumber( _D ) end )( isoStr ) local h, m, s = ( function( str ) local pattern = "T(%d+):(%d+):(%d+)%Z" local _H, _M, _S = mw.ustring.match( str, pattern ) return tonumber( _H ), tonumber( _M ), tonumber( _S ) end )( isoStr ) local oh, om = ( function( str ) if str:sub(-1) == "Z" then -- ends with Z, Zulu time return 0, 0 end -- matches ±hh:mm, ±hhmm or ±hh; else returns nils local pattern = "([-+])(%d%d):?(%d?%d?)$" local sign, oh, om = mw.ustring.match( str, pattern ) sign, oh, om = sign or "+", oh or "00", om or "00" return tonumber( sign .. oh ), tonumber( sign .. om ) end )( isoStr ) return { year=Y, month=M, day=D, hour=( h + oh ), min=( m + om ), sec=s } end ---Внутренняя функции для получения границ временного диапазона ---@param time string ---@param precision number ---@return table | nil function p._parseTimeBoundaries( time, precision ) local s = splitISO8601( time ) if not s then return nil end if precision >= 0 and precision <= 8 then local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 } local power = powers[ precision + 1 ] local left = s.year - ( s.year % power ) return { tonumber( os.time( { year=left, month=1, day=1, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 9 then return { tonumber( os.time( { year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000, tonumber( os.time( { year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 } end if precision == 10 then local lastDays = { 31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } local lastDay = lastDays[ s.month ] return { tonumber( os.time( { year=s.year, month=s.month, day=1, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 11 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 12 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 13 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58 } ) ) * 1000 + 1999 } end if precision == 14 then local t = tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) return { t * 1000, t * 1000 + 999 } end error( 'Unsupported precision: ' .. precision ) end ---Внутренняя функция для получения числового значения времени из snak'а ---@param table snak ---@return number | nil function p._parseTimeFromSnak( snak ) if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time then local timeData = splitISO8601( tostring( snak.datavalue.value.time ) ) timeData.month = math.max( timeData.month, 1 ) timeData.day = math.max( timeData.day, 1 ) return tonumber( os.time( timeData ) ) * 1000 end return nil end ---Функция для формирования категории на основе wikidata/config ---@param options table ---@param entityId string ---@return string local function extractCategory( options, entityId ) if not entityId or not options.category or options.nocat then return '' end if type( entityId ) ~= 'string' then entityId = entityId.id end local claims = WDS.load( entityId, options.category ) if not claims then return '' end for _, claim in pairs( claims ) do if claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.type == 'wikibase-entityid' then local catEntityId = claim.mainsnak.datavalue.value.id local wbStatus, catSiteLink = pcall( mw.wikibase.getSitelink, catEntityId ) if wbStatus and catSiteLink then return '[[' .. catSiteLink .. ']]' end end end return '' end ---Преобразует строку в булевое значение ---@param valueToParse string ---@return boolean Преобразованное значение, если его удалось распознать, или defaultValue во всех остальных случаях local function toBoolean( valueToParse, defaultValue ) if valueToParse ~= nil then if valueToParse == false or valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then return false end return true end return defaultValue end ---Обрачивает отформатированное значение в инлайновый или блочный тег. ---@param value string value ---@param attributes table of attributes ---@return string HTML tag with value local function wrapValue( value, attributes ) local tagName = 'span' local spacer = '' if string.match( value, '\n' ) or string.match( value, '<t[dhr][ >]' ) or string.match( value, '<div[ >]' ) or string.find( value, 'UNIQ%-%-imagemap' ) then tagName = 'div' spacer = '\n' end local attrString = '' for key, val in pairs( attributes or {} ) do local _key = mw.text.trim( key ) local _value = mw.text.encode( mw.text.trim( val ) ) attrString = attrString .. _key .. '="' .. _value .. '" ' end return '<' .. tagName .. ' ' .. attrString .. '>' .. spacer .. value .. '</' .. tagName .. '>' end ---Wraps formatted snak value into HTML tag with attributes. ---@param value string value of snak ---@param hash string ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapSnak( value, hash, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'class' ] = ( newAttributes[ 'class' ] or '' ) .. ' wikidata-snak' if hash then newAttributes[ 'data-wikidata-hash'] = hash else newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-main-snak' end return wrapValue( value, newAttributes ) end ---Wraps formatted statement value into HTML tag with attributes. ---@param value string value of statement ---@param propertyId string PID of property ---@param claimId string ID of claim or nil for local value ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapStatement( value, propertyId, claimId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'class' ] = newAttributes[ 'class' ] or '' newAttributes[ 'data-wikidata-property-id' ] = string.upper( propertyId ) if claimId then newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-claim' newAttributes[ 'data-wikidata-claim-id' ] = claimId else newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' no-wikidata' end return wrapValue( value, newAttributes ) end ---Wraps formatted qualifier's statement value into HTML tag with attributes. ---@param value string value of qualifier's statement ---@param qualifierId string PID of qualifier ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapQualifier( value, qualifierId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'data-wikidata-qualifier-id' ] = string.upper( qualifierId ) return wrapValue( value, newAttributes ) end ---Функция для получения сущности (еntity) для текущей страницы ---Подробнее о сущностях см. d:Wikidata:Glossary/ru ---@param id string Идентификатор (типа P18, Q42) ---@return table Таблица, элементы которой индексируются с нуля local function getEntityFromId( id ) local entity local wbStatus if id then wbStatus, entity = pcall( mw.wikibase.getEntity, id ) else wbStatus, entity = pcall( mw.wikibase.getEntity ) end return entity end ---Внутренняя функция для формирования сообщения об ошибке ---@param key string Ключ элемента в таблице config.errors (например entity-not-found) ---@return void local function throwError( key ) error( getConfig( 'errors', key ) ) end ---Функция для получения идентификатора сущностей ---@param value table ---@return string local function getEntityIdFromValue( value ) local prefix = '' if value[ 'entity-type' ] == 'item' then prefix = 'Q' elseif value[ 'entity-type' ] == 'property' then prefix = 'P' else throwError( 'unknown-entity-type' ) end return prefix .. value[ 'numeric-id' ] end ---Проверка на наличие специализированной функции в опциях ---@param options table ---@param prefix string ---@return function local function getUserFunction( options, prefix, defaultFunction ) -- проверка на указание специализированных обработчиков в параметрах, -- переданных при вызове if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then -- проверка на пустые строки в параметрах или их отсутствие if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then throwError( 'unknown-' .. prefix .. '-module' ) end -- динамическая загруза модуля с обработчиком указанным в параметре local formatter = require( 'Module:' .. options[ prefix .. '-module' ] ) if formatter == nil then throwError( prefix .. '-module-not-found' ) end local fun = formatter[ options[ prefix .. '-function' ] ] if fun == nil then throwError( prefix .. '-function-not-found' ) end return fun end return defaultFunction end ---Выбирает свойства по property id, дополнительно фильтруя их по рангу ---@param context table ---@param options table ---@param propertySelector string ---@return table | nil local function selectClaims( context, options, propertySelector ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entity is missing' ); end if not propertySelector then error( 'propertySelector not specified' ); end local result = WDS.load( options.entityId, propertySelector ) if not result or #result == 0 then return nil end if options.limit and options.limit ~= '' and options.limit ~= '-' then local limit = tonumber( options.limit, 10 ) while #result > limit do table.remove( result ) end end return result end ---Функция для получения значения свойства элемента в заданный момент времени. ---@param entityId string ---@param boundaries table Временные границы ---@param propertyIds table<string> ---@param selectors table<string> ---@return table Таблица соответствующих значений свойства local function getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ) if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type(entityId)); end local results = {} if not propertyIds or #propertyIds == 0 then return results end for i, propertyId in ipairs( propertyIds ) do local selector if selectors ~= nil then selector = selectors[ i ] or selectors[ propertyId ] or propertyId else selector = propertyId end local fakeAllClaims = {} fakeAllClaims[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId ) local filteredClaims = WDS.filter( fakeAllClaims, selector .. '[rank:preferred, rank:normal]' ) if filteredClaims then for _, claim in pairs( filteredClaims ) do if not boundaries then if not claim.qualifiers or not claim.qualifiers.P582 then table.insert( results, claim.mainsnak ) end else local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' ) local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' ) if ( startBoundaries == nil or startBoundaries[ 1 ] <= boundaries[ 1 ] ) and ( endBoundaries == nil or endBoundaries[ 1 ] >= boundaries[ 2 ] ) then table.insert( results, claim.mainsnak ) end end end end if #results > 0 then break end end return results end ---@param context table ---@param propertyId string ---@return table | nil function p.getTimeBoundariesFromProperty( context, propertyId ) local dateClaims = WDS.filter( context.entity.claims, propertyId ) if not dateClaims or #dateClaims == 0 then return nil; end -- only support exact date so far, but need improvment local left = nil local right = nil for _, claim in pairs( dateClaims ) do if not claim.mainsnak then return nil end local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak ) if not boundaries then return nil end left = min( left, boundaries[ 1 ] ) right = max( right, boundaries[ 2 ] ) end if not left or not right then return nil end return { left, right } end ---@param context table ---@param propertyIds table<string> ---@return table | nil function p.getTimeBoundariesFromProperties( context, propertyIds ) for _, propertyId in ipairs( propertyIds ) do local result = p.getTimeBoundariesFromProperty( context, propertyId ); if result then return result end end return nil end ---@param context table ---@param statement table ---@param qualifierId string ---@return table | nil function p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId ) -- only support exact date so far, but need improvement local left, right if statement.qualifiers and statement.qualifiers[ qualifierId ] then for _, qualifier in pairs( statement.qualifiers[ qualifierId ] ) do local boundaries = context.parseTimeBoundariesFromSnak( qualifier ) if not boundaries then return nil end left = min( left, boundaries[ 1 ] ) right = max( right, boundaries[ 2 ] ) end end if not left or not right then return nil end return { left, right } end ---@param _ table ---@param context table ---@param statement table ---@param qualifierIds table<string> ---@return table | nil function p.getTimeBoundariesFromQualifiers( _, context, statement, qualifierIds ) if not qualifierIds then qualifierIds = { 'P582', 'P580', 'P585' } end for _, qualifierId in pairs( qualifierIds ) do local result = p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId ) if result then return result end end return nil end ---@type table<string> local getLabelWithLang_DEFAULT_PROPERTIES = { 'P1813', 'P1448', 'P1705' } ---@type table<string> local getLabelWithLang_DEFAULT_SELECTORS = { 'P1813[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]', 'P1448[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]', 'P1705[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]' } ---Функция для получения метки элемента в заданный момент времени. ---@param context table ---@param options table ---@param entityId string ---@param boundaries table ---@param propertyIds table ---@param selectors table<string> ---@return string, string Текстовая метка элемента, язык метки local function getLabelWithLang( context, options, entityId, boundaries, propertyIds, selectors ) if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type( entityId ) ); end if not entityId then return nil end local langCode = CONTENT_LANGUAGE_CODE -- name from label local label if options.text and options.text ~= '' then label = options.text else if not propertyIds then propertyIds = getLabelWithLang_DEFAULT_PROPERTIES selectors = getLabelWithLang_DEFAULT_SELECTORS end -- name from properties local results = getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ) for _, result in pairs( results ) do if result.datavalue and result.datavalue.value then if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then label = result.datavalue.value.text langCode = result.datavalue.value.language break elseif result.datavalue.type == 'string' then label = result.datavalue.value break end end end if not label then label, langCode = mw.wikibase.getLabelWithLang( entityId ) if not langCode then return nil end end end return label, langCode end ---@param context table ---@param options table ---@return string local function formatPropertyDefault( context, options ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entityId missing' ); end local claims if options.property then -- TODO: Почему тут может не быть property? if options.rank then -- передать настройки ранга из конфига claims = context.selectClaims( options, options.property .. options.rank ) else claims = context.selectClaims( options, options.property ) end end if claims == nil then return '' --TODO error? end -- Обход всех заявлений утверждения и с накоплением оформленных предпочтительных -- заявлений в таблице local formattedClaims = {} for _, claim in pairs( claims ) do local formattedStatement = context.formatStatement( options, claim ) -- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil if formattedStatement and formattedStatement ~= '' then if not options.plain then formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id ) end table.insert( formattedClaims, formattedStatement ) end end -- создание текстовой строки со списком оформленых заявлений из таблицы local out = mw.text.listToText( formattedClaims, options.separator, options.conjunction ) if out ~= '' then if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end ---Create context ---@param initOptions table ---@return table | nil local function initContext( initOptions ) local context = { entityId = initOptions.entityId, entity = initOptions.entity, extractCategory = extractCategory, formatSnak = formatSnak, formatPropertyDefault = formatPropertyDefault, formatStatementDefault = formatStatementDefault, getPropertyInBoundaries = getPropertyInBoundaries, getTimeBoundariesFromProperty = p.getTimeBoundariesFromProperty, getTimeBoundariesFromProperties = p.getTimeBoundariesFromProperties, getTimeBoundariesFromQualifier = p.getTimeBoundariesFromQualifier, getTimeBoundariesFromQualifiers = p.getTimeBoundariesFromQualifiers, parseTimeFromSnak = p._parseTimeFromSnak, getLabelWithLang = getLabelWithLang, wrapSnak = wrapSnak, wrapStatement = wrapStatement, wrapQualifier = wrapQualifier, } context.cloneOptions = function( options ) local entity = options.entity options.entity = nil local newOptions = mw.clone( options ) options.entity = entity newOptions.entity = entity newOptions.frame = options.frame; -- На склонированном фрейме frame:expandTemplate() return newOptions end context.formatProperty = function( options ) local func = getUserFunction( options, 'property', context.formatPropertyDefault ) return func( context, options ) end context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end context.parseTimeBoundariesFromSnak = function( snak ) if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision then return p._parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision ) end return nil end context.getSourcingCircumstances = function( statement ) return getSourcingCircumstances( statement ) end context.selectClaims = function( options, propertyId ) return selectClaims( context, options, propertyId ) end return context end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@param options table ---@return string Formatted wikitext. local function formatProperty( options ) -- Получение сущности по идентификатору local entity = getEntityFromId( options.entityId ) if not entity then return -- throwError( 'entity-not-found' ) end -- проверка на присутсвие у сущности заявлений (claim) -- подробнее о заявлениях см. d:Викиданные:Глоссарий if not entity.claims then return '' --TODO error? end -- improve options options.frame = g_frame options.entity = entity options.extends = function( self, newOptions ) return copyTo( newOptions, copyTo( self, {} ) ) end if options.i18n then options.i18n = copyTo( options.i18n, copyTo( getConfig( 'i18n' ), {} ) ) else options.i18n = getConfig( 'i18n' ) end local context = initContext( options ) return context.formatProperty( options ) end ---Функция для оформления одного утверждения (statement) ---@param context table ---@param options table ---@param statement table ---@return string Formatted wikitext. function formatStatement( context, options, statement ) if not statement then error( 'statement is not specified or nil' ) end if not statement.type or statement.type ~= 'statement' then throwError( 'unknown-claim-type' ) end local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault ) return functionToCall( context, options, statement ) end ---@param statement table ---@return table function getSourcingCircumstances( statement ) if not statement then error( 'statement is not specified' ) end local circumstances = {} if statement.qualifiers and statement.qualifiers.P1480 then for _, qualifier in pairs( statement.qualifiers.P1480 ) do if qualifier and qualifier.datavalue and qualifier.datavalue.type == 'wikibase-entityid' and qualifier.datavalue.value and qualifier.datavalue.value[ 'entity-type'] == 'item' then table.insert( circumstances, qualifier.datavalue.value.id ) end end end return circumstances end ---Функция для оформления одного утверждения (statement) ---@param context table Context. ---@param options table Parameters. ---@param statement table ---@return string Formatted wikitext. function formatStatementDefault( context, options, statement ) if not context then error( 'context is not specified' ) end if not options then error( 'options is not specified' ) end if not statement then error( 'statement is not specified' ) end local circumstances = context.getSourcingCircumstances( statement ) options.qualifiers = statement.qualifiers local result = context.formatSnak( options, statement.mainsnak, circumstances ) if options.qualifier and statement.qualifiers and statement.qualifiers[ options.qualifier ] then local qualifierConfig = getPropertyParams( options.qualifier, nil, {} ) if options.i18n then qualifierConfig.i18n = options.i18n end if qualifierConfig.datatype == 'time' then qualifierConfig.nolinks = true end local qualifierValues = {} for _, qualifierSnak in pairs( statement.qualifiers[ options.qualifier ] ) do local snakValue = context.formatSnak( qualifierConfig, qualifierSnak ) if snakValue and snakValue ~= '' then table.insert( qualifierValues, snakValue ) end end if result and result ~= '' and #qualifierValues then if qualifierConfig.invisible then result = result .. table.concat( qualifierValues, ', ' ) else result = result .. ' (' .. table.concat( qualifierValues, ', ' ) .. ')' end end end if result and result ~= '' and options.references then result = result .. context.formatRefs( options, statement ) end return result end ---Функция для оформления части утверждения (snak) ---Подробнее о snak см. d:Викиданные:Глоссарий ---@param context table Context. ---@param options table Parameters. ---@param snak table ---@param circumstances table ---@return string Formatted wikitext. function formatSnak( context, options, snak, circumstances ) circumstances = circumstances or {} local result if snak.snaktype == 'somevalue' then if options[ 'somevalue' ] and options[ 'somevalue' ] ~= '' then result = options[ 'somevalue' ] else result = options.i18n[ 'somevalue' ] end elseif snak.snaktype == 'novalue' then if options[ 'novalue' ] and options[ 'novalue' ] ~= '' then result = options[ 'novalue' ] else result = options.i18n[ 'novalue' ] end elseif snak.snaktype == 'value' then result = formatDatavalue( context, options, snak.datavalue, snak.datatype ) for _, item in pairs( circumstances ) do if options.i18n[ item ] then result = options.i18n[ item ] .. result end end else throwError( 'unknown-snak-type' ) end if not result or result == '' then return nil end if options.plain then return result end return context.wrapSnak( result, snak.hash ) end ---Функция для оформления объектов-значений с географическими координатами ---@param value string Raw value. ---@param options table Parameters. ---@return string Formatted string. local function formatGlobeCoordinate( value, options ) -- проверка на требование в параметрах вызова на возврат сырого значения if options[ 'subvalue' ] == 'latitude' then -- широты return value[ 'latitude' ] elseif options[ 'subvalue' ] == 'longitude' then -- долготы return value[ 'longitude' ] elseif options[ 'nocoord' ] and options[ 'nocoord' ] ~= '' then -- если передан параметр nocoord, то не выводить координаты -- обычно это делается при использовании нескольких карточек на странице return '' else -- в противном случае формируются параметры для вызова шаблона {{coord}} -- нужно дописать в документации шаблона, что он отсюда вызывается, и что -- любое изменние его парамеров должно быть согласовано с кодом тут local coordModule = require( 'Module:Coordinates' ) local globe = options.globe or '' if globe == '' and value[ 'globe' ] then local globes = require( 'Module:Wikidata/Globes' ) globe = globes[ value[ 'globe' ] ] or '' end local display = 'inline' if options.display and options.display ~= '' then display = options.display elseif ( options.property:upper() == 'P625' ) then display = 'title' end local format = options.format or '' if format == '' then format = 'dms' if value[ 'precision' ] then local precision = value[ 'precision' ] * 60 if precision >= 60 then format = 'd' elseif precision >= 1 then format = 'dm' end end end g_frame.args = { tostring( value[ 'latitude' ] ), tostring( value[ 'longitude' ] ), globe = globe, type = options.type and options.type or '', scale = options.scale and options.scale or '', display = display, format = format, } return coordModule.coord(g_frame) end end ---Функция для оформления объектов-значений с файлами с Викисклада ---@param value string Raw value. ---@param options table Parameters. ---@return string Formatted string. local function formatCommonsMedia( value, options ) local image = value local caption = '' if options[ 'caption' ] and options[ 'caption' ] ~= '' then caption = options[ 'caption' ] end if caption ~= '' then caption = wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } ) end if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then -- если в value не содержится викикод или imagemap, то викифицируем имя файла -- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[phab:T28213]] image = '[[File:' .. value .. '|frameless' if options[ 'border' ] and options[ 'border' ] ~= '' then image = image .. '|border' end local size = options[ 'size' ] if size and size ~= '' then -- TODO: check localized pixel names too if not string.match( size, 'px$' ) then size = size .. 'px' end else size = fileDefaultSize end image = image .. '|' .. size if options[ 'alt' ] and options[ 'alt' ] ~= '' then image = image .. '|alt=' .. options[ 'alt' ] end if caption ~= '' then image = image .. '|' .. caption end image = image .. ']]' if caption ~= '' then image = image .. '<br>' .. caption end else image = image .. caption .. getCategoryByCode( 'media-contains-markup' ) end return image end ---Function for render math formulas ---@param value string Value. ---@param options table Parameters. ---@return string Formatted string. local function formatMath( value, options ) return options.frame:extensionTag{ name = 'math', content = value } end ---Функция для оформления внешних идентификаторов ---@param value string ---@param options table ---@return string local function formatExternalId( value, options ) local formatter = options.formatter local propertyId = options.property:upper() if not formatter or formatter == '' then local isGoodFormat = false local wbStatus, formatRegexStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1793' ) if wbStatus and formatRegexStatements then for _, statement in pairs( formatRegexStatements ) do if statement.mainsnak.snaktype == 'value' then local pattern = mw.ustring.gsub( statement.mainsnak.datavalue.value, '\\', '%' ) pattern = mw.ustring.gsub( pattern, '{%d+,?%d*}', '+' ) if ( string.find( pattern, '|' ) or string.find( pattern, '%)%?' ) or mw.ustring.match( value, '^' .. pattern .. '$' ) ~= nil ) then isGoodFormat = true break end end end end if isGoodFormat then local formatterStatements wbStatus, formatterStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1630' ) if wbStatus and formatterStatements then for _, statement in pairs( formatterStatements ) do if statement.mainsnak.snaktype == 'value' then formatter = statement.mainsnak.datavalue.value break end end end end end if formatter and formatter ~= '' then local encodedValue = mw.ustring.gsub( value, '%%', '%%%%' ) -- ломается, если подставить внутрь другого mw.ustring.gsub local link = mw.ustring.gsub( mw.ustring.gsub( formatter, '$1', encodedValue ), '.', { [ ' ' ] = '%20', [ '+' ] = '%2b', [ '[' ] = '%5B', [ ']' ] = '%5D' } ) local title = options.title if not title or title == '' then title = '$1' end title = mw.ustring.gsub( mw.ustring.gsub( title, '$1', encodedValue ), '.', { [ '[' ] = '(', [ ']' ] = ')' } ) return '[' .. link .. ' ' .. title .. ']' end return value end ---Функция для оформления числовых значений ---@param value table Объект-значение ---@param options table Таблица параметров ---@return string Оформленный текст local function formatQuantity( value, options ) -- диапазон значений local amount = string.gsub( value.amount, '^%+', '' ) local lang = mw.language.getContentLanguage() local langCode = lang:getCode() local function formatNum( number, sigfig ) local multiplier = '' if options.countByThousands then local powers = options.i18n.thousandPowers local pos = 1 while math.abs( number ) >= 1000 and pos < #powers do number = number / 1000 pos = pos + 1 end multiplier = powers[ pos ] if math.abs( number ) >= 100 then sigfig = sigfig or 0 elseif math.abs( number ) >= 10 then sigfig = sigfig or 1 else sigfig = sigfig or 2 end else sigfig = sigfig or 12 -- округление до 12 знаков после запятой, на 13-м возникает ошибка в точности end local iMultiplier = 10^sigfig number = math.floor( number * iMultiplier + 0.5 ) / iMultiplier return string.gsub( lang:formatNum( number ), '^-', '−' ) .. multiplier end local out = formatNum( tonumber( amount ) ) if value.upperBound then local diff = tonumber( value.upperBound ) - tonumber( amount ) if diff > 0 then -- временная провека, пока у большинства значений не будет убрано ±0 -- Пробуем понять до какого знака округлять local integer, dot, decimals, _ = value.upperBound:match( '^+?-?(%d*)(%.?)(%d*)(.*)' ) local precision if dot == '' then precision = -integer:match( '0*$' ):len() else precision = #decimals end local bound = formatNum( diff, precision ) if string.match( bound, 'E%-(%d+)' ) then -- если в экспоненциальном формате local digits = tonumber( string.match( bound, 'E%-(%d+)' ) ) - 2 bound = formatNum( diff * 10 ^ digits, precision ) bound = string.sub( bound, 0, 2 ) .. string.rep( '0', digits ) .. string.sub( bound, -string.len( bound ) + 2 ) end out = out .. ' ± ' .. bound end end if options.unit and options.unit ~= '' then if options.unit ~= '-' then out = out .. ' ' .. options.unit end elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' ) if unitEntityId ~= 'undefined' then local wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ) if wbStatus == true and unitEntity then if unitEntity.claims.P2370 and unitEntity.claims.P2370[ 1 ].mainsnak.snaktype == 'value' and not value.upperBound and options.siConversion == true then local conversionToSiUnit = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.amount, '^%+', '' ) if math.floor( math.log10( conversionToSiUnit ) ) ~= math.log10( conversionToSiUnit ) then -- Если не степени десятки (переводить сантиметры в метры не надо!) local outValue = tonumber( amount ) * conversionToSiUnit if outValue > 0 then -- Пробуем понять до какого знака округлять local integer, dot, decimals, _ = amount:match( '^(%d*)(%.?)(%d*)(.*)' ) local precision if dot == '' then precision = -integer:match( '0*$' ):len() else precision = #decimals end local adjust = math.log10( math.abs( conversionToSiUnit ) ) + math.log10( 2 ) local minPrecision = 1 - math.floor( math.log10( outValue ) + 2e-14 ) out = formatNum( outValue, math.max( math.floor( precision + adjust ), minPrecision ) ) else out = formatNum( outValue, 0 ) end unitEntityId = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.unit, 'http://www.wikidata.org/entity/', '' ) wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ) end end local label = getLabelWithLang( context, options, unitEntity.id, nil, { "P5061", "P558", "P558" }, { 'P5061[language:' .. langCode .. ']', 'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']', 'P558[!P282][!P407]' } ) out = out .. ' ' .. label end end end return out end ---Функция для оформления URL ---@param context table ---@param options table ---@param value string local function formatUrlValue( context, options, value ) if not options.length or options.length == '' then options.length = 25 end local moduleUrl = require( 'Module:URL' ) return moduleUrl.formatUrlSingle( context, options, value ) end local DATATYPE_CACHE = {} ---Get property datatype by ID. ---@param propertyId string Property ID, e.g. 'P123'. ---@return string Property datatype, e.g. 'commonsMedia', 'time' or 'url'. local function getPropertyDatatype( propertyId ) if not propertyId or not string.match( propertyId, '^P%d+$' ) then return nil end local cached = DATATYPE_CACHE[ propertyId ] if cached ~= nil then return cached end local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, propertyId ) if wbStatus ~= true or not propertyEntity then return nil end mw.log("Loaded datatype " .. propertyEntity.datatype .. " of " .. propertyId .. ' from wikidata, consider passing datatype argument to formatProperty call or to Wikidata/config' ) DATATYPE_CACHE[ propertyId ] = propertyEntity.datatype return propertyEntity.datatype end ---@param datavalue table ---@return function local function getPlainValueFunction( datavalue, _ ) if datavalue.type == 'wikibase-entityid' then return function( _, _, value ) return getEntityIdFromValue( value ) end elseif datavalue.type == 'string' then return function( _, _, value ) return value end elseif datavalue.type == 'monolingualtext' then return function( _, _, value ) return value.text end elseif datavalue.type == 'globecoordinate' then return function( _, _, value ) return value.latitude .. ',' .. value.longitude end elseif datavalue.type == 'quantity' then return function( _, _, value ) return value.amount end elseif datavalue.type == 'time' then return function( _, _, value ) return value.time end end throwError( 'unknown-datavalue-type' ) end ---@param datavalue table ---@param datatype string ---@return function local function getDefaultValueFunction( datavalue, datatype ) -- вызов обработчиков по умолчанию для известных типов значений if datavalue.type == 'wikibase-entityid' then -- Entity ID return function( context, options, value ) return formatEntityId( context, options, getEntityIdFromValue( value ) ) end elseif datavalue.type == 'string' then -- String if datatype and datatype == 'commonsMedia' then -- Media return function( _, options, value ) return formatCommonsMedia( value, options ) end elseif datatype and datatype == 'external-id' then -- External ID return function( _, options, value ) return formatExternalId( value, options ) end elseif datatype and datatype == 'math' then -- Math formula return function( _, options, value ) return formatMath( value, options ) end elseif datatype and datatype == 'url' then -- URL return formatUrlValue end return function( _, _, value ) return value end elseif datavalue.type == 'monolingualtext' then -- моноязычный текст (строка с указанием языка) return function( _, options, value ) if options.monolingualLangTemplate == 'lang' then if value.language == CONTENT_LANGUAGE_CODE then return value.text end return options.frame:expandTemplate{ title = 'lang-' .. value.language, args = { value.text } } elseif options.monolingualLangTemplate == 'ref' then return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language } else return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' end end elseif datavalue.type == 'globecoordinate' then -- географические координаты return function( _, options, value ) return formatGlobeCoordinate( value, options ) end elseif datavalue.type == 'quantity' then return function( _, options, value ) return formatQuantity( value, options ) end elseif datavalue.type == 'time' then return function( context, options, value ) local moduleDate = require( 'Module:Wikidata/date' ) return moduleDate.formatDate( context, options, value ) end end -- во всех стальных случаях возвращаем ошибку throwError( 'unknown-datavalue-type' ) end ---Функция для оформления значений (value) ---Подробнее о значениях см. d:Wikidata:Glossary/ru ---@param context table ---@param options table ---@param datavalue table ---@param datatype string ---@return string Оформленный текст function formatDatavalue( context, options, datavalue, datatype ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not datavalue then error( 'datavalue not specified' ); end if not datavalue.value then error( 'datavalue.value is missing' ); end -- проверка на указание специализированных обработчиков в параметрах, -- переданных при вызове if options.plain then context.formatValueDefault = getPlainValueFunction( datavalue, datatype ) else context.formatValueDefault = getDefaultValueFunction( datavalue, datatype ) end local functionToCall = getUserFunction( options, 'value', context.formatValueDefault ) return functionToCall( context, options, datavalue.value ) end local DEFAULT_BOUNDARIES = { os.time() * 1000, os.time() * 1000} ---Функция для оформления идентификатора сущности ---@param context table ---@param options table ---@param entityId string ---@return string Оформленный текст function formatEntityId( context, options, entityId ) -- получение локализованного названия local boundaries if options.qualifiers then boundaries = p.getTimeBoundariesFromQualifiers( context.frame, context, { qualifiers = options.qualifiers } ) end if not boundaries then boundaries = DEFAULT_BOUNDARIES end local label, labelLanguageCode = getLabelWithLang( context, options, entityId, boundaries ) -- определение соответствующей показываемому элементу категории local category = context.extractCategory( options, { id = entityId } ) -- получение ссылки по идентификатору local link = mw.wikibase.sitelink( entityId ) if link then -- ссылка на категорию, а не добавление страницы в неё if mw.ustring.match( link, '^' .. mw.site.namespaces[ 14 ].name .. ':' ) then link = ':' .. link end if label and not options.rawArticle then if labelLanguageCode ~= CONTENT_LANGUAGE_CODE then label = '<span lang="' .. label .. '">' .. label .. '</span>' end local a = '[[' .. link .. '|' .. label .. ']]' if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then a = a .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' ) end return a .. category else return '[[' .. link .. ']]' .. category end end if label then -- TODO: возможно, лучше просто mw.wikibase.getLabel(entityId) -- красная ссылка -- TODO: разобраться, почему не всегда есть options.frame local moduleRedLink = require( 'Module:Wikidata/redLink' ) local title = mw.title.new( label ) if title and not title.exists and options.frame then local rawLabel = mw.wikibase.getLabel(entityId) or label -- без |text= и boundaries; or label - костыль local redLink = moduleRedLink.formatRedLinkWithInfobox(rawLabel, label, entityId) if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then redLink = '<span lang="' .. labelLanguageCode .. '">' .. redLink .. '</span>' .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' ) end return redLink .. category end -- TODO: перенести до проверки на существование статьи local addWdLink = false if ( not options.format or options.format ~= 'text' ) and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: переписать на format=text then addWdLink = true end -- одноимённая статья уже существует - выводится текст и ссылка на ВД return moduleRedLink.formatText(label, entityId, addWdLink) .. category end -- сообщение об отсутвии локализованного названия -- not good, but better than nothing return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. getCategoryByCode( 'links-to-entities-with-missing-label' ) .. category end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@deprecated Use p.formatProperty() instead ---@param frame table ---@return string Строка оформленного текста, предназначенная для отображения в статье function p.formatStatements( frame ) return p.formatProperty( frame ) end ---Получение параметров, которые обычно используются для вывода свойства. ---@param propertyId string ---@param datatype string ---@param params table function getPropertyParams( propertyId, datatype, params ) local config = getConfig() -- Различные уровни настройки параметров, по убыванию приоритета local propertyParams = {} -- 1. Параметры, указанные явно при вызове if params then for key, value in pairs( params ) do if value ~= '' then propertyParams[ key ] = value end end end if toBoolean( propertyParams.plain, false ) then propertyParams.separator = propertyParams.separator or ', ' propertyParams.conjunction = propertyParams.conjunction or ', ' else -- 2. Настройки конкретного параметра if config.properties and config.properties[ propertyId ] then for key, value in pairs( config.properties[ propertyId ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end -- 3. Указанный пресет настроек if propertyParams.preset and config.presets and config.presets[ propertyParams.preset ] then for key, value in pairs( config.presets[ propertyParams.preset ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end datatype = datatype or params.datatype or propertyParams.datatype or getPropertyDatatype( propertyId ) if propertyParams.datatype == nil then propertyParams.datatype = datatype end -- 4. Настройки для типа данных if datatype and config.datatypes and config.datatypes[ datatype ] then for key, value in pairs( config.datatypes[ datatype ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end -- 5. Общие настройки для всех свойств if config.global then for key, value in pairs( config.global ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end end return propertyParams end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@param frame table ---@return string Строка оформленного текста, предназначенная для отображения в статье function p.formatProperty( frame ) local args = copyTo( frame.args, {} ) -- проверка на отсутствие обязательного параметра property if not args.property then throwError( 'property-param-not-provided' ) end local override local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '([^Pp0-9].*)$', function(w) if string.sub( w, 1, 1 ) == '~' then override = w end return '' end ) ) if override then args[ override:match( '[,~]([^=]*)=' ) ] = override:match( '=(.*)' ) args.property = propertyId end -- проброс всех параметров из шаблона {wikidata} и параметра from откуда угодно local p_frame = frame while p_frame do if p_frame:getTitle() == mw.site.namespaces[ 10 ].name .. ':Wikidata' then copyTo( p_frame.args, args, true ) end if p_frame.args and p_frame.args.from and p_frame.args.from ~= '' then args.entityId = p_frame.args.from else args.entityId = mw.wikibase.getEntityIdForCurrentPage() end p_frame = p_frame:getParent() end args = getPropertyParams( propertyId, nil, args ) local datatype = args.datatype -- перевод итоговых значений флагов в true/false и добавление значений -- по умолчанию только в том случае, если они нигде не были указаны ранее args.plain = toBoolean( args.plain, false ) args.nocat = not args.plain and toBoolean( args.nocat, false ) args.references = not args.plain and toBoolean( args.references, true ) -- если значение передано в параметрах вызова то выводим только его if args.value and args.value ~= '' then -- специальное значение для скрытия Викиданных if args.value == '-' then return '' end local value = args.value -- опция, запрещающая оформление значения, поэтому никак не трогаем if args.plain then return value end local context = initContext( args ) -- обработчики по типу значения local wrapperExtraArgs = {} if args[ 'value-module' ] and args[ 'value-function' ] and not string.find( value, '[%[%]%{%}]' ) then local func = getUserFunction( args, 'value' ) value = func( context, args, value ) elseif datatype == 'commonsMedia' then value = formatCommonsMedia( value, args ) elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then wrapperExtraArgs[ 'data-wikidata-external-id' ] = mw.text.killMarkers( value ) value = formatExternalId( value, args ) --elseif datatype == 'math' then -- args.frame = frame -- костыль: в formatMath нужно frame:extensionTag -- value = formatMath( value, args ) elseif datatype == 'url' then value = formatUrlValue( context, args, value ) end -- оборачиваем в тег для JS-функций if string.match( propertyId, '^P%d+$' ) then value = mw.text.trim( value ) -- временная штрафная категория для исправления табличных вставок local allowTables = getPropertyParams( propertyId, nil, {} ).allowTables if not allowTables and string.match( value, '<t[dhr][ >]' ) -- and not string.match( value, '<table[ >]' ) -- and not string.match( value, '^%{%|' ) then value = value .. getCategoryByCode( 'value-contains-table', propertyId ) else value = wrapStatement( value, propertyId, nil, wrapperExtraArgs ) end end return value end -- ability to disable loading Wikidata if args.entityId == '-' then return '' end g_frame = frame -- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений) return formatProperty( args ) end ---Функция проверки на присутствие источника в списке нерекомендованных. ---@param snaks table ---@return boolean local function isReferenceDeprecated( snaks ) if not snaks then return false end if snaks.P248 and snaks.P248[ 1 ] and snaks.P248[ 1 ].datavalue and snaks.P248[ 1 ].datavalue.value.id then local entityId = snaks.P248[ 1 ].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end elseif snaks.P1433 and snaks.P1433[ 1 ] and snaks.P1433[ 1 ].datavalue and snaks.P1433[ 1 ].datavalue.value.id then local entityId = snaks.P1433[ 1 ].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end end return false end ---Функция оформления ссылок на источники (reference) ---Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru --- ---Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context ---Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства). ---@param context table ---@param options table ---@param statement table ---@return string Оформленные примечания для отображения в статье function formatRefs( context, options, statement ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entityId missing' ); end if not statement then error( 'statement not specified' ); end if not outputReferences then return '' end ---@type string[] local references = {} if statement.references then local hasNotDeprecated = false local displayCount = 0 for _, reference in pairs( statement.references ) do if not isReferenceDeprecated( reference.snaks ) then hasNotDeprecated = true end end for _, reference in pairs( statement.references ) do local display = true if hasNotDeprecated then if isReferenceDeprecated( reference.snaks ) then display = false end end if displayCount >= 2 then if options.entityId and options.property then local propertyId = mw.ustring.match( options.property, '^[Pp][0-9]+' ) -- TODO: обрабатывать не тут, а раньше local moreReferences = '<sup>[[d:' .. options.entityId .. '#' .. string.upper( propertyId ) .. '|[…]]]</sup>' table.insert( references, moreReferences ) end break end if display == true then ---@type string local refText = moduleSources.renderReference( g_frame, options.entityId, reference ) if refText and refText ~= '' then table.insert( references, refText ) displayCount = displayCount + 1 end end end end return table.concat( references ) end return p 4558f762f30c6ebfb9f5333dbd7ebda83c6873f2 Модуль:Sources 828 83 177 176 2025-01-31T15:24:23Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain ---@alias args table ---@alias frame { args: args, extensionTag: function, newChild: ( fun( args: args ): frame ) } ---@alias source { publication: source, [string]: any } ---@alias value: string | { id: string } ---@alias snak { datatype: string, snaktype: string, datavalue: { type: string, value: value } } ---@alias snaks table<string, table<number, snak>> ---@alias statement { mainsnak: snak, rank: string, qualifiers: snaks } ---@alias statements table<string, table<number, statement>> ---@alias map { name: string, ids: string[] }[]> ---@type table local p = {} ---@type table<string, string> local NORMATIVE_DOCUMENTS = { Q20754888 = 'Закон Российской Федерации', Q20754884 = 'Закон РСФСР', Q20873831 = 'Распоряжение Президента Российской Федерации', Q20873834 = 'Указ исполняющего обязанности Президента Российской Федерации', Q2061228 = 'Указ Президента Российской Федерации', } ---@type table<string, string> local LANG_CACHE = { Q150 = 'fr', Q188 = 'de', Q1321 = 'es', Q1860 = 'en', Q652 = 'it', Q7737 = 'ru', Q8798 = 'uk', } ---@type map local PROPERTY_MAP = { { name = 'sourceId', ids = { 'P248', 'P805' } }, { name = 'lang', ids = { 'P407', 'P364' } }, { name = 'author', ids = { 'P50', 'P2093' } }, { name = 'part', ids = { 'P958', 'P1810' } }, { name = 'title', ids = { 'P1476' } }, { name = 'subtitle', ids = { 'P1680' } }, { name = 'url', ids = { 'P953', 'P1065', 'P854', 'P973', 'P2699', 'P888' } }, { name = 'editor', ids = { 'P98' } }, { name = 'translator', ids = { 'P655' } }, { name = 'publication-id', ids = { 'P1433' } }, { name = 'edition', ids = { 'P393' } }, { name = 'publisher', ids = { 'P123' } }, { name = 'place', ids = { 'P291' } }, { name = 'volume', ids = { 'P478' } }, { name = 'issue', ids = { 'P433' } }, { name = 'dateOfCreation', ids = { 'P571' } }, { name = 'dateOfPublication', ids = { 'P577' } }, { name = 'pages', ids = { 'P304' } }, { name = 'numberOfPages', ids = { 'P1104' } }, { name = 'tirage', ids = { 'P1092' } }, { name = 'isbn', ids = { 'P212', 'P957' } }, { name = 'issn', ids = { 'P236' } }, -- { name = 'accessdate', ids = { 'P813' } }, -- disable, creates duplicate references { name = 'docNumber', ids = { 'P1545' } }, { name = 'type', ids = { 'P31' } }, { name = 'arxiv', ids = { 'P818' } }, { name = 'doi', ids = { 'P356' } }, { name = 'pmid', ids = { 'P698' } }, } -- table.insert( PROPERTY_MAP.url, 'P856' ) -- only as qualifier ---@type map local PUBLICATION_PROPERTY_MAP = mw.clone( PROPERTY_MAP ) ---@type string[] local monthGen = { 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' } ---@type string local i18nDefaultLanguage = mw.language.getContentLanguage():getCode() p.i18nDefaultLanguage = i18nDefaultLanguage ---@type string local i18nEtAlDefault = ' et al.' ---@type table<string, string> local i18nEtAl = { ru = ' и др.', uk = ' та ін.', } ---@type table<string, string> local i18nEditors = { fr = '', de = 'Hrsg.: ', es = '', en = '', it = '', ru = 'под ред. ', uk = 'за ред. ', } ---@type table<string, string> local i18nTranslators = { fr = '', de = '', es = '', en = '', it = '', ru = 'пер. ', uk = 'пер. ', } ---@type table<string, string> local i18nVolume = { de = 'Vol.', fr = 'Vol.', es = 'Vol.', en = 'Vol.', it = 'Vol.', ru = 'Т.', uk = 'Т.', } ---@type table<string, string> local i18nIssue = { en = 'Iss.', ru = 'вып.', uk = 'вип.', } ---@type table<string, string> local i18nPages = { fr = 'P.', de = 'S.', es = 'P.', en = 'P.', it = 'P.', ru = 'С.', uk = 'С.', } ---@type table<string, string> local i18nNumberOfPages = { en = 'p.', ru = 'с.', } ---@type table<string, string> local i18nTirage = { en = 'ed. size: %d', ru = '%d экз.', } ---@param args args ---@return source local function getFilledArgs( args ) ---@type source local data = {} for key, value in pairs( args ) do if mw.text.trim( value ) ~= '' then if key == 1 then key = 'sourceId' end data[ key ] = mw.text.trim( value ) end end return data end ---Returns formatted pair {Family name(s), First name(s)} ---@param fullName string ---@return table<number, string> local function tokenizeName( fullName ) local space = '%s+' -- matches single or more spacing character local name = "(%a[%a%-']*)%.?" -- matches single name, have to start with letter, can contain apostrophe and hyphen, may end with dot local surname = "(%a[%a%-']*)" -- same as name, but can't end with dot local surnamePrefixes = { 'ван', 'van', 'де', 'de' } local nm, nm2, srn, srn2, pref fullName = ' ' .. fullName .. ' ' fullName = mw.ustring.gsub( fullName, ' оглы ', ' ' ) fullName = mw.text.trim( fullName ) -- Surname, Name local pattern = '^' .. surname .. ',' .. space .. name .. '$' srn, nm = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.' } end -- Surname, Name prefix for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. surname .. ',' .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$' srn, nm, pref = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.' } end end -- Surname, Name Name pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. '$' srn, nm, nm2 = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end -- Surname Surname, Name pattern = '^' .. surname .. space .. surname .. ',' .. space .. name .. '$' srn, srn2, nm = mw.ustring.match( fullName, pattern ) if srn then return { srn .. '&nbsp;' .. srn2, mw.ustring.sub( nm, 1, 1 ) .. '.' } end -- Name Name Surname pattern = '^' .. name .. space .. name .. space .. surname .. '$' nm, nm2, srn = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end -- Name Name prefix Surname for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. space .. surname .. '$' nm, nm2, pref, srn = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end end -- Surname, Name Name prefix for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$' srn, nm, nm2, pref = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end end -- Name{1,4} Surname for k = 1, 4 do pattern = '^' .. string.rep( name .. space, k ) .. surname .. '$' ---@type string[] local matched = { mw.ustring.match( fullName, pattern ) } if #matched ~= 0 then for j = 1, k do matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 ) end return { matched[ k + 1 ], table.concat( matched, '.&nbsp;', 1, k ) .. '.' } end end -- Surname Name{1,4} for k = 1, 4 do pattern = '^' .. surname .. string.rep( space .. name, k ) .. '$' ---@type string[] local matched = { mw.ustring.match( fullName, pattern ) } if #matched ~= 0 then for j = 2, k + 1 do matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 ) end return { matched[ 1 ], table.concat( matched, '.&nbsp;', 2, k + 1 ) .. '.' } end end return { fullName } end ---@param fullName string | nil ---@return string | nil local function personNameToAuthorName( fullName ) if not fullName then return nil end local tokenized = tokenizeName( fullName ) if #tokenized == 1 then return tokenized[ 1 ] end return tokenized[ 1 ] .. '&nbsp;' .. tokenized[ 2 ] end ---@param fullName string | nil ---@return string | nil local function personNameToResponsibleName( fullName ) if not fullName then return nil end local tokenized = tokenizeName( fullName ) if #tokenized == 1 then return tokenized[ 1 ] end return tokenized[ 2 ] .. '&nbsp;' .. tokenized[ 1 ] end ---@alias options { separator: string, conjunction: string, format: ( fun( data: string ): string ), nolinks: boolean, preferids: boolean, short: boolean } ---@type options local options_commas = { separator = ', ', conjunction = ', ', format = function( data ) return data end, nolinks = false, preferids = false, short = false, } ---@type options local options_commas_short = mw.clone( options_commas ) options_commas_short.short = true ---@type options local options_commas_it_short = mw.clone( options_commas_short ) options_commas_it_short.format = function( data ) return "''" .. data .. "''" end ---@type options local options_commas_nolinks = mw.clone( options_commas ) options_commas_nolinks.nolinks = true ---@type options local options_citetypes = { separator = ' ', conjunction = ' ', format = function( data ) return 'citetype_' .. data end, nolinks = true , preferids = true, short = false, } ---@type options local options_commas_authors = mw.clone( options_commas ) options_commas_authors.format = personNameToAuthorName ---@type options local options_commas_responsible = mw.clone( options_commas ) options_commas_responsible.format = personNameToResponsibleName ---@type options local options_ids = { separator = '; ', conjunction = '; ', format = function( id ) return id end, nolinks = true, preferids = false, short = false, } ---@type options local options_arxiv = mw.clone( options_ids ) options_arxiv.format = function( id ) return '[https://arxiv.org/abs/' .. id .. ' arXiv:' .. id .. ']' end ---@type options local options_doi = mw.clone( options_ids ) options_doi.format = function( doi ) return '[https://dx.doi.org/' .. doi .. ' doi:' .. doi .. ']' end ---@type options local options_issn = mw.clone( options_ids ) options_issn.format = function( issn ) return '[https://www.worldcat.org/issn/' .. issn .. ' ' .. issn .. ']' end ---@type options local options_pmid = mw.clone( options_ids ) options_pmid.format = function( pmid ) return '[https://www.ncbi.nlm.nih.gov/pubmed/?term=' .. pmid .. ' PMID:' .. pmid .. ']' end ---@param str string | nil ---@return boolean local function isEmpty( str ) return not str or #str == 0 end ---@param allQualifiers snaks ---@param qualifierPropertyId string ---@return string | nil local function getSingleStringQualifierValue( allQualifiers, qualifierPropertyId ) if not allQualifiers or not allQualifiers[ qualifierPropertyId ] then return nil end ---@type table<number, snak> local propertyQualifiers = allQualifiers[ qualifierPropertyId ] for _, qualifier in pairs( propertyQualifiers ) do if ( qualifier and qualifier.datatype == 'string' and qualifier.datavalue and qualifier.datavalue.type == 'string' and qualifier.datavalue.value ~= '' ) then return qualifier.datavalue.value end end return nil end ---@param data table ---@param resultProperty string ---@return void local function appendImpl_toTable( data, resultProperty ) if not data[ resultProperty ] then data[ resultProperty ] = {} elseif ( type( data[ resultProperty ] ) == 'string' or ( type( data[ resultProperty ] ) == 'table' and type( data[ resultProperty ].id ) == 'string' ) ) then data[ resultProperty ] = { data[ resultProperty ] } end end ---@param datavalue table ---@param qualifiers snaks ---@param data table ---@param propertyName string ---@param options table local function appendImpl( datavalue, qualifiers, data, propertyName, options ) data[ propertyName ] = data[ propertyName ] or {} if propertyName == 'issn' then table.insert( data[ propertyName ], datavalue.value ) elseif propertyName == 'url' or datavalue.type == 'url' then local value = datavalue.value if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'string' then local value = getSingleStringQualifierValue( qualifiers, 'P1932' ) if not value then value = getSingleStringQualifierValue( qualifiers, 'P1810' ) end if not value then value = datavalue.value if options.format then value = options.format( value ) end end appendImpl_toTable(data, propertyName) local pos = getSingleStringQualifierValue( qualifiers, 'P1545' ) if pos then table.insert( data[ propertyName ], tonumber(pos), value ) else table.insert( data[ propertyName ], value ) end elseif datavalue.type == 'monolingualtext' then local value = datavalue.value.text if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'quantity' then local value = datavalue.value.amount if ( mw.ustring.sub( value , 1, 1 ) == '+' ) then value = mw.ustring.sub( value , 2 ) end if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'wikibase-entityid' then local pos = getSingleStringQualifierValue( qualifiers, 'P1545' ) local value = datavalue.value appendImpl_toTable(data, propertyName) local label = getSingleStringQualifierValue( qualifiers, 'P1932' ) if not label then label = getSingleStringQualifierValue( qualifiers, 'P1810' ) end local toInsert = { id = value.id, label = label } if pos and tonumber( pos ) then table.insert( data[ propertyName ], tonumber( pos ), toInsert ) else table.insert( data[ propertyName ], toInsert ) end elseif datavalue.type == 'time' then local value = datavalue.value if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], tostring( value.time ) ) end end ---@param entityId string ---@param propertyId string ---@return table<number, statement> local function getAllStatements( entityId, propertyId ) ---@type boolean, table<number, statement> local wdStatus, statements = pcall( mw.wikibase.getAllStatements, entityId, propertyId ) if wdStatus and statements then return statements end return {} end ---@param entityId string ---@param propertyId string ---@return table<number, statement> local function getBestStatements( entityId, propertyId ) ---@type boolean, table<number, statement> local wdStatus, statements = pcall( mw.wikibase.getBestStatements, entityId, propertyId ) if wdStatus and statements then return statements end return {} end ---@param entityId string ---@param projectToCheck string? ---@return string | nil local function getSitelink( entityId, projectToCheck ) ---@type boolean, string local wbStatus, sitelink if projectToCheck then wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId, projectToCheck ) else wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId ) end if not wbStatus then return nil end return sitelink end ---@param args any[] ---@return any | nil local function coalesce( args ) for _, arg in pairs( args ) do if not isEmpty( arg ) then return arg end end return nil end ---@param value any ---@return string | nil local function getSingle( value ) if type( value ) == 'string' then return tostring( value ) elseif type( value ) == 'table' then if value.id then return tostring( value.id ) end for _, tableValue in pairs( value ) do return getSingle( tableValue ) end end return nil end ---@param langEntityId string ---@return string | nil local function getLangCode( langEntityId ) if not langEntityId then return nil end langEntityId = getSingle( langEntityId ) if not string.match( langEntityId, '^Q%d+$' ) then return langEntityId end local cached = LANG_CACHE[ langEntityId ] if cached then if cached == '' then return nil end return cached end local claims = getBestStatements( langEntityId, 'P424' ) for _, claim in pairs( claims ) do if claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value then LANG_CACHE[ langEntityId ] = claim.mainsnak.datavalue.value return claim.mainsnak.datavalue.value end end LANG_CACHE[ langEntityId ] = '' return nil end ---@param entityId string ---@param propertyId string ---@param data source ---@param propertyName string ---@param options table? ---@return void local function appendEntitySnaks( entityId, propertyId, data, propertyName, options ) options = options or {} -- do not populate twice if data[ propertyName ] and ( propertyName ~= 'author' or data[ propertyId ] ) then return end local statements = getBestStatements( entityId, propertyId ) if propertyName == 'author' then data[ propertyId ] = true end local lang = getLangCode( data.lang ) or i18nDefaultLanguage if propertyId == 'P1680' then -- if there is a default language for _, statement in pairs( statements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value and statement.mainsnak.datavalue.value.language == lang then --found default language string appendImpl( statement.mainsnak.datavalue, statement.qualifiers, data, propertyName, options ) return end end end for _, statement in pairs( statements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue then appendImpl( statement.mainsnak.datavalue, statement.qualifiers or {}, data, propertyName, options ) if propertyName == 'publication-id' and statement.qualifiers then data[ 'publication-qualifiers' ] = statement.qualifiers end end end end ---@param claims table<number, statement> ---@param qualifierPropertyId string ---@param result table ---@param resultPropertyId string ---@param options table ---@return void local function appendQualifiers( claims, qualifierPropertyId, result, resultPropertyId, options ) -- do not populate twice if not claims or result[ resultPropertyId ] then return end for _, claim in pairs( claims ) do if claim.qualifiers and claim.qualifiers[ qualifierPropertyId ] then ---@type table<number, snak> local propertyQualifiers = claim.qualifiers[ qualifierPropertyId ] for _, qualifier in pairs( propertyQualifiers ) do if qualifier and qualifier.datavalue then appendImpl( qualifier.datavalue, nil, result, resultPropertyId, options ) end end end end end ---@param entityId string ---@param propertyId string ---@param value any ---@return table<number, statement> local function findClaimsByValue( entityId, propertyId, value ) local result = {} local claims = getAllStatements( entityId, propertyId ) for _, claim in pairs( claims ) do if ( claim.mainsnak and claim.mainsnak.datavalue ) then local datavalue = claim.mainsnak.datavalue if ( datavalue.type == "string" and datavalue.value == value ) or ( datavalue.type == "wikibase-entityid" and datavalue.value[ "entity-type" ] == "item" and tostring( datavalue.value.id ) == value ) then table.insert( result, claim ) end end end return result end ---@param entityId string ---@param typeEntityId string ---@return boolean local function isInstanceOf( entityId, typeEntityId ) return findClaimsByValue( entityId, 'P31', typeEntityId )[ 1 ] ~= nil end ---@param entityId string ---@param typeEntityIds string[] ---@return string ---@todo Rewrite local function getFirstType( entityId, typeEntityIds ) for _, typeEntityId in pairs( typeEntityIds ) do if isInstanceOf( entityId, typeEntityId ) then return typeEntityId end end return nil end ---@param snaks snaks ---@param data source ---@param map map ---@return void local function populateDataFromSnaks( snaks, data, map ) for _, row in ipairs( map ) do local parameterName, propertyIds = row.name, row.ids for _, propertyId in pairs( propertyIds ) do if not data[ parameterName ] and snaks[ propertyId ] then local options = {} if propertyId == 'P888' then options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end } end for _, snak in pairs( snaks[ propertyId ] ) do if snak and snak.datavalue then appendImpl( snak.datavalue, {}, data, parameterName, options ) end end end end end end ---@param entityId string | nil ---@param data source ---@param map map ---@return void local function populateDataFromEntity( entityId, data, map ) if not data.title then if not isEmpty( entityId ) then local optionsAsLinks = { format = function( text ) return { id = entityId, label = text } end } appendEntitySnaks( entityId, 'P1476', data, 'title', optionsAsLinks ) else appendEntitySnaks( entityId, 'P1476', data, 'title', {} ) end appendEntitySnaks( entityId, 'P1680', data, 'subtitle', {} ) end local bookSeriesStatements = getBestStatements( entityId, 'P361' ) for _, statement in pairs( bookSeriesStatements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value and statement.mainsnak.datavalue.value.id then local possibleBookSeriesEntityId = statement.mainsnak.datavalue.value.id if isInstanceOf( possibleBookSeriesEntityId, 'Q277759' ) then appendImpl_toTable( data, 'bookSeries' ) table.insert( data.bookSeries, { id = possibleBookSeriesEntityId } ) appendQualifiers( { statement }, 'P478', data, 'bookSeriesVolume', {} ) appendQualifiers( { statement }, 'P433', data, 'bookSeriesIssue', {} ) end end end for _, row in ipairs( map ) do local parameterName, propertyIds = row.name, row.ids for _, propertyId in pairs( propertyIds ) do local options = {} if propertyId == 'P888' then options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end } end appendEntitySnaks( entityId, propertyId, data, parameterName, options ) end end end ---@param data source ---@return void local function expandPublication( data ) if not data[ 'publication-id' ] then return end local publicationId = getSingle( data[ 'publication-id' ] ) data.publication = {} for key, value in pairs( data ) do if not string.match( key, '^publication-' ) then data.publication[ key ] = value end end data.publication.sourceId = publicationId data.publication.title = data[ 'publication-title' ] data.publication.subtitle = data[ 'publication-subtitle' ] if data[ 'publication-qualifiers' ] then populateDataFromSnaks( data[ 'publication-qualifiers' ], data.publication, PUBLICATION_PROPERTY_MAP ) end populateDataFromEntity( publicationId, data.publication, PUBLICATION_PROPERTY_MAP ) if type( data.publication.title ) == 'table' and data.publication.title[ 1 ] then data.publication.title = data.publication.title[ 1 ] end if type( data.publication.subtitle ) == 'table' and data.publication.subtitle[ 1 ] then data.publication.subtitle = data.publication.subtitle[ 1 ] end for key, value in pairs( data.publication ) do if key ~= 'sourceId' and key ~= 'title' and key ~= 'subtitle' and key ~= 'url' and not data[ key ] then data[ key ] = value end end end ---@param data source ---@return void local function expandBookSeries( data ) local bookSeries = data.bookSeries if not bookSeries then return end -- use only first one if type( bookSeries ) == 'table' and bookSeries[ 1 ] and bookSeries[ 1 ].id then data.bookSeries = bookSeries[ 1 ] bookSeries = data.bookSeries end if not bookSeries or not bookSeries.id then return end appendEntitySnaks( bookSeries.id, 'P123', data, 'publisher', {} ) appendEntitySnaks( bookSeries.id, 'P291', data, 'place', {} ) appendEntitySnaks( bookSeries.id, 'P236', data, 'issn', {} ) end ---@param entityId string ---@return string | nil local function getNormativeTitle( entityId ) local possibleTypeIds = {} for typeId, _ in pairs( NORMATIVE_DOCUMENTS ) do table.insert( possibleTypeIds, typeId ) end local foundTypeId = getFirstType( entityId, possibleTypeIds ) if foundTypeId then return NORMATIVE_DOCUMENTS[ foundTypeId ] end return nil end ---@param urls table<number, string> | string ---@param text string ---@return string local function wrapInUrl( urls, text ) local url = getSingle( urls ) if string.sub( url, 1, 1 ) == ':' then return '[[' .. url .. '|' .. text .. ']]' else return '[' .. url .. ' ' .. text .. ']' end end ---@param entityId string ---@param lang string ---@return string local function getElementLink( entityId, lang ) local sitelink = getSitelink( entityId, nil ) if sitelink then return ':' .. sitelink end if lang ~= 'mul' then -- link to entity in source language sitelink = getSitelink( entityId, lang .. 'wiki' ) if sitelink then return ':' .. lang .. ':' .. sitelink end end return ':d:' .. entityId end ---@param entityId string ---@param lang string ---@return string local function getLabel( entityId, lang ) local wbStatus, label = pcall( mw.wikibase.getLabelByLang, entityId, lang ) if not wbStatus then return '' end if label and label ~= '' then return label end wbStatus, label = pcall( mw.wikibase.getLabel, entityId ) if not wbStatus then return '' end return label or '' end ---@param lang string ---@param entityId string ---@param customTitle string ---@param options table local function renderLink( lang, entityId, customTitle, options ) if not entityId then error( 'entityId is not specified' ) end if type( entityId ) ~= 'string' then error( 'entityId is not string, but ' .. type( entityId ) ) end if type( customTitle or '' ) ~= 'string' then error( 'customTitle is not string, but ' .. type( customTitle ) ) end local title = customTitle -- ISO 4 if isEmpty( title ) then local propertyStatements = getBestStatements( entityId, 'P1160' ) for _, claim in pairs( propertyStatements ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == lang ) then title = claim.mainsnak.datavalue.value.text -- mw.log( 'Got title of ' .. entityId .. ' from ISO 4 claim: «' .. title .. '»' ) break end end end -- official name P1448 -- short name P1813 if isEmpty( title ) and options.short then local propertyStatements = getBestStatements( entityId, 'P1813' ) for _, claim in pairs( propertyStatements ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == lang ) then title = claim.mainsnak.datavalue.value.text -- mw.log( 'Got title of ' .. entityId .. ' from short name claim: «' .. title .. '» (' .. lang .. ')' ) break end end end -- person name P1559 -- labels if isEmpty( title ) then title = getLabel( entityId, lang ) -- mw.log( 'Got title of ' .. entityId .. ' from label: «' .. title .. '» (' .. lang .. ')' ) end local actualText = title or '\'\'(untranslated)\'\'' local link = getElementLink( entityId, lang ) return wrapInUrl( link, actualText ) end ---@param lang string ---@param value value ---@param options options ---@return string local function asString( lang, value, options ) if type( value ) == 'string' then return options.format( value ) end if type( value ) ~= 'table' then return options.format( '(unknown type)' ) end if value.id then -- this is link if type( value.label or '' ) ~= 'string' then mw.logObject( value, 'error value' ) error( 'label of table value is not string but ' .. type( value.label ) ) end local title if options.preferids then title = value.id elseif options.nolinks then title = value.label or getLabel( value.id, lang ) else title = renderLink( lang, value.id, value.label, options ) end if title == '' then title = "''(untranslated title)''" end return options.format( title ) end local resultList = {} for _, tableValue in pairs( value ) do table.insert( resultList, asString( lang, tableValue, options ) ) end return mw.text.listToText( resultList, options.separator, options.conjunction ) end ---@param entityId string ---@param data source ---@return source local function populateSourceDataImpl( entityId, data, map ) local wsLink = getSitelink( entityId, 'ruwikisource' ) if wsLink and not mw.ustring.gmatch( wsLink, 'Категория:' ) then data.url = ":ru:s:" .. wsLink end populateDataFromEntity( entityId, data, map ) local normativeTitle = getNormativeTitle( entityId ) if normativeTitle then local y, m, d = mw.ustring.match( getSingle( data.dateOfCreation ) , "(%-?%d+)%-(%d+)%-(%d+)T" ) y, m, d = tonumber( y ),tonumber( m ), tonumber( d ) local title = asString( 'ru', data.title, options_commas_nolinks ) local docNumber = getSingle( data.docNumber ) data.title = { normativeTitle .. " от&nbsp;" .. tostring( d ) .. "&nbsp;" .. monthGen[ m ] .. " " .. tostring( y ) .. "&nbsp;г." .. ( docNumber and ( " №&nbsp;" .. docNumber ) or '' ) .. ' «' .. title.. '»' } end if not data.title then local lang = getLangCode( data.lang ) or i18nDefaultLanguage local label = getLabel( entityId, lang ) if label ~= '' then data.title = { label } end end return data end ---@param entityId string ---@param propertyId string ---@param data source ---@return void local function expandSpecialsQualifiers( entityId, propertyId, data ) local statements = getBestStatements( entityId, propertyId ) for _, statement in pairs( statements ) do populateDataFromSnaks( statement.qualifiers or {}, data, PROPERTY_MAP ) end end ---Expand special types of references when additional data could be found in OTHER entity properties ---@param data source ---@return void local function expandSpecials( data ) if not data.entityId then return end if data.sourceId == 'Q36578' then -- Gemeinsame Normdatei -- specified by P227 appendEntitySnaks( data.entityId, 'P227', data, 'part', { format = function(gnd ) return 'Record #' .. gnd; end } ) appendEntitySnaks( data.entityId, 'P227', data, 'url', { format = function(gnd ) return 'http://d-nb.info/gnd/' .. gnd .. '/'; end } ) data.year = '2012—2016' expandSpecialsQualifiers( data.entityId, 'P227', data ) elseif data.sourceId == 'Q15222191' then -- BNF -- specified by P268 appendEntitySnaks( data.entityId, 'P268', data, 'part', { format = function(id ) return 'Record #' .. id; end } ) appendEntitySnaks( data.entityId, 'P268', data, 'url', { format = function(id ) return 'http://catalogue.bnf.fr/ark:/12148/cb' .. id; end } ) expandSpecialsQualifiers( data.entityId, 'P268', data ) elseif data.sourceId == 'Q54919' then -- VIAF -- specified by P214 appendEntitySnaks( data.entityId, 'P214', data, 'part', { format = function(id ) return 'Record #' .. id; end } ) appendEntitySnaks( data.entityId, 'P214', data, 'url', { format = function(id ) return 'https://viaf.org/viaf/' .. id; end } ) expandSpecialsQualifiers( data.entityId, 'P214', data ) else -- generic property search for _, sourceClaim in pairs( getBestStatements( data.sourceId, 'P1687' ) ) do if sourceClaim.mainsnak.snaktype == 'value' then local sourcePropertyId = sourceClaim.mainsnak.datavalue.value.id for _, sourcePropertyClaim in pairs( getBestStatements( sourcePropertyId, 'P1630' ) ) do if sourcePropertyClaim.mainsnak.snaktype == 'value' then appendEntitySnaks( data.entityId, sourcePropertyId, data, 'url', { format = function( id ) return mw.ustring.gsub( mw.ustring.gsub( sourcePropertyClaim.mainsnak.datavalue.value, '$1', id ), ' ', '%%20' ) end } ) expandSpecialsQualifiers( data.entityId, sourcePropertyId, data ) break end end end end end -- do we have appropriate record in P1433 ? local claims = findClaimsByValue( currentEntityId, 'P1343', data.sourceId ) if claims and #claims ~= 0 then for _, claim in pairs( claims ) do populateDataFromSnaks( claim.qualifiers, data, PROPERTY_MAP ) populateDataFromEntity( data.sourceId, data, PROPERTY_MAP ) end end end ---@param text string ---@param tip string ---@return string local function toTextWithTip( text, tip ) return '<span title="' .. tip .. '" style="border-bottom: 1px dotted; cursor: help; white-space: nowrap">' .. text .. '</span>' end ---@param lang string ---@param placeId string ---@return string local function getPlaceName( placeId, lang ) -- ГОСТ Р 7.0.12—2011 if lang == 'ru' then if placeId == 'Q649' then return toTextWithTip( 'М.', 'Москва' ); end if placeId == 'Q656' then return toTextWithTip( 'СПб.', 'Санкт-Петербург' ); end if placeId == 'Q891' then return toTextWithTip( 'Н. Новгород', 'Нижний Новгород' ); end if placeId == 'Q908' then return toTextWithTip( 'Ростов н/Д.', 'Ростов-на-Дону' ); end end return nil end ---@param data source ---@param lang string ---@return void local function preprocessPlace( data, lang ) if not data.place then return end ---@type table<number, string> local newPlace = {} for index, place in pairs( data.place ) do if place.id then local newPlaceStr = getPlaceName( place.id, lang ) if newPlaceStr then newPlace[ index ] = newPlaceStr else newPlace[ index ] = getLabel( place.id, lang ) end else newPlace[ index ] = place end end data.place = newPlace end ---@param entityId string ---@param lang string ---@param providedLabel string | nil ---@param options options ---@return string local function getPersonNameAsLabel( entityId, lang, providedLabel, options ) -- would custom label provided we don't need to check entity at all if not isEmpty( providedLabel ) then return options.format( providedLabel ) end if lang == 'mul' then lang = i18nDefaultLanguage end ---@type string | nil local personName = getLabel( entityId, lang ) if isEmpty( personName ) then return '\'\'(not translated to ' .. lang .. ')\'\'' end if not isInstanceOf( entityId, 'Q5' ) then return personName end return options.format( personName ) end ---@param entityId string ---@param lang string ---@param customLabel string | nil ---@param options options ---@return string local function getPersonNameAsWikitext( entityId, lang, customLabel, options ) local personName = getPersonNameAsLabel( entityId, lang, customLabel, options ) local link = getElementLink( entityId, lang ) return wrapInUrl( link, personName ) end ---@param value value ---@param lang string ---@param options options ---@return string local function getPeopleAsWikitext( value, lang, options ) if type( value ) == 'string' then return options.format( value ) elseif type( value ) == 'table' then if value.id then -- this is link if options.preferids then return tostring( value.id ) else if options.nolinks then return getPersonNameAsLabel( value.id, lang, value.label, options ) else return getPersonNameAsWikitext( value.id, lang, value.label, options ) end end end local maxAuthors = 10 -- need some restrictions, as some publications have enormous amount of authors (e.g. 115 authors of Q68951544) local resultList = {} for _, tableValue in pairs( value ) do local nextWikitext = getPeopleAsWikitext( tableValue, lang, options ) if not isEmpty( nextWikitext ) then table.insert( resultList, nextWikitext ) if #resultList == maxAuthors + 1 then -- keep one more to indicate that there are too many break end end end local resultWikitext = '' for i, wikitext in pairs( resultList ) do if i == maxAuthors + 1 then resultWikitext = resultWikitext .. ( i18nEtAl[ lang ] or i18nEtAlDefault ) break end if i ~= 1 then resultWikitext = resultWikitext .. ', ' end resultWikitext = resultWikitext .. wikitext end return resultWikitext end return '' -- options.format( '(unknown type)' ) end ---@param lang string ---@param data source ---@return string local function generateAuthorLinks( lang, data ) local result = '' if data.author then result = getPeopleAsWikitext( data.author, lang, options_commas_authors ) result = '<i class="wef_low_priority_links">' .. result .. '</i> ' end return result end ---@param lang string ---@param data source ---@param conjunction string ---@param propertyName string ---@param urlPropertyName string? ---@return string local function appendProperty( lang, data, conjunction, propertyName, urlPropertyName ) if not data[ propertyName ] then return '' end local out if urlPropertyName and data[ urlPropertyName ] then out = wrapInUrl( data[ urlPropertyName ], asString( lang, data[ propertyName ], options_commas_nolinks ) ) else out = asString( lang, data[ propertyName ], options_commas ) end if not out or out == '' then return '' end return conjunction .. out end ---@param lang string ---@param data source ---@return string local function appendTitle( lang, data ) local conjunction = '' local result = '' if data.part then result = result .. appendProperty( lang, data, '', 'part', 'parturl' ) conjunction = ' // ' end return result .. appendProperty( lang, data, conjunction, 'title', 'url' ) end ---@param lang string ---@return string local function appendLanguage( lang ) if lang == i18nDefaultLanguage then return '' end ---@type { getRefHtml: ( fun( lang: string ): string ), list_ref: ( fun( frame: frame ): string ) } local langs = require( 'Module:Languages' ) return langs.list_ref( p.currentFrame:newChild{ args = { lang } } ) end ---@param lang string ---@param data source ---@return string local function appendSubtitle( lang, data ) return appendProperty( lang, data, ': ', 'subtitle', nil ) end ---@param lang string ---@param data source ---@return string local function appendOriginalTitle( lang, data ) return appendProperty( lang, data, ' = ', 'originaltitle', nil ) end ---@param lang string ---@param data source ---@return string local function appendPublication( lang, data ) if not data.publication then return '' end local result = ' // ' .. asString( lang, data.publication.title, options_commas_it_short ) if data.publication.subtitle and data.publication.subtitle ~= '' then result = result .. ': ' .. asString( lang, data.publication.subtitle, options_commas_it_short ) end return result end ---@param lang string ---@param data source ---@return string local function appendEditor( lang, data ) if not data.editor and not data.translator then return '' end local result = ' / ' if data.editor then local prefix = i18nEditors[ lang ] or i18nEditors[ i18nDefaultLanguage ] result = result .. prefix .. getPeopleAsWikitext( data.editor, lang, options_commas_responsible ) if data.translator then result = result .. ', ' end end if data.translator then local prefix = i18nTranslators[ lang ] or i18nTranslators[ i18nDefaultLanguage ] result = result .. prefix .. getPeopleAsWikitext( data.translator, lang, options_commas_responsible ) end return result end ---@param lang string ---@param data source local function appendEdition( lang, data ) return appendProperty( lang, data, ' — ', 'edition', nil ) end ---@param lang string ---@param data source ---@return string local function appendPublicationData( lang, data ) if not data.place and not data.publisher and not data.year then return '' end local result = ' — ' if data.place then result = result .. asString( lang, data.place, options_commas_short ) if data.publisher or data.year then result = result .. ': ' end end if data.publisher then result = result .. asString( lang, data.publisher, options_commas_short ) if data.year then result = result .. ', ' end end if data.year then result = result .. asString( lang, data.year, options_commas ) end result = result .. '.' return result end ---@param lang string ---@param data source ---@return string local function appendVolumeAndIssue( lang, data ) if not data.volume and not data.issue then return '' end local result = ' — ' local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ] local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ] if data.volume then result = result .. appendProperty( lang, data, letter_vol .. '&nbsp;', 'volume', nil ) result = result ..appendProperty( lang, data, ', ' .. letter_iss .. '&nbsp;', 'issue', nil ) else result = result .. appendProperty( lang, data, letter_iss .. '&nbsp;', 'issue', nil ) end result = result .. '.' return result end ---@param lang string ---@param data source ---@return string local function appendPages( lang, data ) if not data.pages then return '' end local letter = i18nPages[ lang ] or i18nPages[ i18nDefaultLanguage ] local strPages = asString( lang, data.pages, options_commas ) strPages = mw.ustring.gsub( strPages, '[-—]', '—' ) return ' — ' .. letter .. '&nbsp;' .. strPages .. '.' end ---@param lang string ---@param data source ---@return string local function appendNumberOfPages( lang, data ) if not data.numberOfPages then return '' end local letter = i18nNumberOfPages[ lang ] or i18nNumberOfPages[ i18nDefaultLanguage ] return appendProperty( lang, data, ' — ', 'numberOfPages', nil ) .. '&nbsp;' .. letter end ---@param lang string ---@param data source ---@return string local function appendBookSeries( lang, data ) if not data.bookSeries then return '' end local result = appendProperty( lang, data, ' — (', 'bookSeries', nil ) if data.bookSeriesVolume or data.bookSeriesIssue then result = result .. '; ' local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ] local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ] if data.bookSeriesVolume then result = result .. appendProperty( lang, data, letter_vol .. '&nbsp;', 'bookSeriesVolume', nil ) result = result .. appendProperty( lang, data, ', ' .. letter_iss .. '&nbsp;', 'bookSeriesIssue', nil ) else result = result .. appendProperty( lang, data, letter_iss .. '&nbsp;', 'bookSeriesIssue', nil ) end end result = result .. ')' return result end ---@param lang string ---@param data source ---@return string local function appendTirage( lang, data ) if not data.tirage then return '' end local tirageTemplate = i18nTirage[ lang ] or i18nTirage[ i18nDefaultLanguage ] ---@type options local optionsTirage = { separator = '; ', conjunction = '; ', format = function( _data ) return tostring( mw.ustring.format( tirageTemplate, _data ) ) end, short = false, nolinks = false, preferids = false, } return ' — ' .. asString( lang, data.tirage, optionsTirage ) end ---@param lang string ---@param value string | nil ---@param options options ---@param prefix string? ---@return string local function appendIdentifier( lang, value, options, prefix ) if not value then return '' end return ' — ' .. ( prefix or '' ) .. asString( lang, value, options ) end ---@param result string ---@param lang string ---@param data source ---@return string local function wrapSourceId( result, lang, data ) if not data.sourceId then return result end local citeType = data.type and asString( lang, data.type, options_citetypes ) or 'citetype_unknown' return '<span class="wikidata_cite ' .. citeType .. '" data-entity-id="' .. data.sourceId .. '">' .. result .. '</span>' end ---@param data source ---@return string local function appendAccessDate( data ) if not data.accessdate then return '' end local date = getSingle( data.accessdate ) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local y, m, d = mw.ustring.match( date, pattern ) y, m, d = tonumber( y ), tonumber( m ), tonumber( d ) local date_str = ( d > 0 and ' ' .. tostring( d ) or '' ) .. ( m > 0 and ' ' .. monthGen[ m ] or '' ) .. ( y > 0 and ' ' .. tostring( y ) or '' ) return " <small>Проверено" .. date_str .. ".</small>" end ---@param data source ---@param lang string ---@return void local function populateUrl( data, lang ) if data.sourceId and not data.url then local sitelink = getSitelink( data.sourceId, lang .. 'wikisource' ) if sitelink then data.url = ':' .. lang .. ':s:' .. sitelink end end end ---@param data source ---@return void local function populateYear( data ) if not data.year and data.dateOfPublication then local date = getSingle( data.dateOfPublication ) data.year = mw.ustring.sub( date, 2, 5 ) end if not data.year and data.dateOfCreation then local date = getSingle( data.dateOfCreation ) data.year = mw.ustring.sub( date, 2, 5 ) end end ---@param data source ---@return void local function populateTitle( data ) data.title = data.title or getSingle( data.url ) end ---@param data source ---@return string local function renderSource( data ) local lang = getLangCode( data.lang ) or i18nDefaultLanguage preprocessPlace( data, lang ) populateUrl( data, lang ) populateTitle( data ) if not data.title then return '' end populateYear( data ) local result = generateAuthorLinks( lang, data ) result = result .. appendTitle( lang, data ) result = result .. appendLanguage( lang ) result = result .. appendSubtitle( lang, data ) result = result .. appendOriginalTitle( lang, data ) result = result .. appendPublication( lang, data ) result = result .. '<span class="wef_low_priority_links">' result = result .. appendEditor( lang, data ) -- Might take current editor instead of actual. Use with caution result = result .. appendEdition( lang, data ) result = result .. appendPublicationData( lang, data ) result = result .. appendVolumeAndIssue( lang, data ) result = result .. appendPages( lang, data ) result = result .. appendNumberOfPages( lang, data ) result = result .. appendBookSeries( lang, data ) result = result .. appendTirage( lang, data ) result = result .. appendIdentifier( lang, data.isbn, options_commas, 'ISBN ' ) result = result .. appendIdentifier( lang, data.issn, options_issn, 'ISSN ' ) result = result .. appendIdentifier( lang, data.doi, options_doi, nil ) result = result .. appendIdentifier( lang, data.pmid, options_pmid, nil ) result = result .. appendIdentifier( lang, data.arxiv, options_arxiv, nil ) result = result .. appendAccessDate( data ) result = result .. '</span>' return wrapSourceId( result, lang, data ) end ---@param data source Данные в простом формате, согласованном с модулями формирования библиографического описания ---@param snaks snaks ---@return string | nil local function renderReferenceImpl( data, snaks ) -- не показывать источники с "импортировано из" if snaks.P143 then return nil end -- забрать данные из reference populateDataFromSnaks( snaks or {}, data, PROPERTY_MAP ) data.sourceId = getSingle( data.sourceId ) populateDataFromEntity( data.sourceId, data, PROPERTY_MAP ) expandSpecials( data ) populateSourceDataImpl( data.sourceId, data, PROPERTY_MAP ) expandPublication( data ) expandBookSeries( data ) if next( data ) == nil then return nil end local rendered = renderSource( data ) if mw.ustring.len( rendered ) == 0 then return nil end if data.ref then local anchorValue = 'CITEREF' .. data.ref .. ( coalesce( { data[ 'ref-year' ], data.year } ) or '' ) rendered = '<span class="citation" id="' .. mw.uri.anchorEncode( anchorValue ) .. '">' .. rendered .. '</span>' end return rendered end ---@param frame frame ---@param currentEntityId string | { id: string } ---@param reference table{ snaks: snaks } ---@return string | nil function p.renderSource( frame, currentEntityId, reference ) reference = reference or { snaks = {} } p.currentFrame = frame local data = getFilledArgs( frame.args or {} ) populateDataFromSnaks( reference.snaks, data, PROPERTY_MAP ) data.sourceId = getSingle( data.sourceId ) if not currentEntityId then data.entityId = mw.wikibase.getEntityIdForCurrentPage() elseif type( currentEntityId ) == 'string' then data.entityId = currentEntityId elseif type( currentEntityId ) == 'table' and currentEntityId.id then data.entityId = currentEntityId.id end ---@type string local rendered = renderReferenceImpl( data, reference.snaks or {} ) if not rendered then return '' end return rendered end ---@param frame frame ---@param currentEntityId string ---@param reference table ---@return string function p.renderReference( frame, currentEntityId, reference ) local rendered = p.renderSource( frame, currentEntityId, reference ) if not rendered or rendered == '' then return '' end -- Про выбор алгоритма хеширования см. [[Модуль:Hash]]. Знак подчёркивания в начале позволяет -- исключить ошибку, когда имя сноски — чисто числовое значение, каковыми иногда бывают хеши. return frame:extensionTag( 'ref', rendered, { name = '_' .. mw.hash.hashValue( 'fnv164', rendered ) } ) .. '[[Category:Википедия:Статьи с источниками из Викиданных]]' end ---@param frame frame ---@return string | nil function p.testPersonNameToAuthorName( frame ) return personNameToAuthorName( frame.args[ 1 ] ) end ---@param frame frame ---@return string | nil function p.testPersonNameToResponsibleName( frame ) return personNameToResponsibleName( frame.args[ 1 ] ) end return p 752a204827a41ecd6cf518bdb22da12718bca2ec Модуль:WikidataSelectors 828 84 179 178 2025-01-31T15:24:24Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local i18n = { ["errors"] = { ["rank-not-valid"] = "Некорретное значение приоритета (rank)", ["cant-parse-condition"] = "Не удалось разобрать условие" } } local validRanks = { 'best', 'preferred', 'normal', 'deprecated' } --[[ Internal function for error message Input: key in errors table Output: error message ]] local function throwError( key ) error( i18n.errors[key] ) end local p = {} --[[ Load property and filter statements Input: entityId, selector string Output: filtered statements table ]] function p.load( entityId, propertySelector ) local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' ) if not propertyId then return nil end propertyId = string.upper( propertyId ) local allStatements = {} allStatements[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId ) return p.filter( allStatements, propertySelector ) end --[[ Parse selectors and filter statements Input: statements table, selector string Output: filtered statements table ]] function p.filter( allClaims, propertySelector ) propertySelector = mw.text.trim( propertySelector ) -- Get property ID from selector local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' ) if not propertyId then propertyId = '' end local initPos = #propertyId + 1 propertyId = string.upper( propertyId ) if ( not allClaims ) then return nil end local allPropertyClaims = allClaims[propertyId] if ( not allPropertyClaims ) then return nil end -- Gathering rules local rules = p.matchSelectors( propertySelector, initPos ) -- If there is no rank filter, than default rank is 'best' local isRanked = false for i, subRules in ipairs( rules ) do for j, rule in ipairs( subRules ) do if rule['type'] == 'rank' then isRanked = true break end end end if not isRanked then table.insert( rules, 1, { { type = 'rank', value = 'best' } } ) end -- Execute rules allPropertyClaims = p.applyRules( allPropertyClaims, rules ) return allPropertyClaims end --[[ Match and gather selector rules Input: string with selectors rules, start position Output: rules table ]] function p.matchSelectors( selectorsString, initPos ) local rules = {} local rawRulePattern = '^%s*%[%s*[^%[%]]+%s*%]%s*' local rulePattern = '^%s*%[%s*([^%[%]]+)%s*%]%s*$' if not initPos then initPos = 1 end local rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos ) while rawRule do initPos = initPos + #rawRule rule = mw.ustring.match( rawRule, rulePattern ) rule = mw.text.trim( rule ) local subRules = mw.text.split( rule, '%s*,%s*' ) local commands = {} local comm for i, subRule in ipairs( subRules ) do local isInversed = false if mw.ustring.match( subRule, '^!' ) then isInversed = true subRule = mw.ustring.match( subRule, '^!%s*(.+)$' ) end -- p123[1] if mw.ustring.match( subRule, '^%d+$' ) then table.insert( commands, { type = 'position', value = subRule, inversed = isInversed } ) -- p123[rank:preferred] elseif mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) then rank = mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) table.insert( commands, { type = 'rank', value = rank, inversed = isInversed } ) -- p123[language:xx] elseif mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) then value = mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) table.insert( commands, { type = 'language', value = value, inversed = isInversed } ) -- p123[language!:xx] elseif mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) then value = mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) table.insert( commands, { type = 'language', value = value, inversed = not isInversed } ) -- p123[min] elseif mw.ustring.match( subRule, '^min$' ) then table.insert( commands, { type = 'value_min' } ) -- p123[max] elseif mw.ustring.match( subRule, '^max$' ) then table.insert( commands, { type = 'value_max' } ) -- p123[min:p456] elseif mw.ustring.match( subRule, '^min%s*:%s*[Pp]%d+$' ) then value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' ) table.insert( commands, { type = 'qualifier_min', qualifier = value } ) -- p123[max:p456] elseif mw.ustring.match( subRule, '^max%s*:%s*[Pp]%d+$' ) then value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' ) table.insert( commands, { type = 'qualifier_max', qualifier = value } ) -- p123[unit:q789] elseif mw.ustring.match( subRule, '^unit%s*:%s*[^%[%],:]+$' ) then value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'unit', value = value, inversed = isInversed } ) -- p123[unit!:q789] elseif mw.ustring.match( subRule, '^unit%s*!:%s*[^%[%],:]+$' ) then value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'unit', value = value, inversed = not isInversed } ) -- p123[p456] elseif mw.ustring.match( subRule, '^[Pp]%d+$' ) then qualifier = mw.ustring.match( subRule, '^[Pp]%d+' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = nil, inversed = isInversed } ) -- p123[p456:q789] elseif mw.ustring.match( subRule, '^[Pp]%d+%s*:%s*[^%[%],:]+$' ) then qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*:?' ) value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = value, inversed = isInversed } ) -- p123[p456!:q789] elseif mw.ustring.match( subRule, '^[Pp]%d+%s*!:%s*[^%[%],:]+$' ) then qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*!:?' ) value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = value, inversed = not isInversed } ) -- p123[q456] elseif mw.ustring.match( subRule, '^[Qq]%d+$' ) then value = mw.ustring.match( subRule, '^[Qq]%d+' ) table.insert( commands, { type = 'value', value = value, inversed = isInversed } ) else throwError( 'cant-parse-condition' ) end end if #commands then table.insert( rules, commands ) end rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos ) end return rules end --[[ Intercept statements with selector rules Input: statements table, selector rules Output: filtered statements table ]] function p.applyRules( claims, rules ) for i, subRules in ipairs( rules ) do local newClaims = {} for j, rule in ipairs( subRules ) do if rule['type'] == 'rank' then table.insert( newClaims, p.filterByRank( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'language' then table.insert( newClaims, p.filterByLanguage( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'unit' then table.insert( newClaims, p.filterByUnit( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'position' then table.insert( newClaims, p.filterByPosition( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'qualifier' then table.insert( newClaims, p.filterByQualifier( claims, rule['qualifier'], rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'qualifier_min' then table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], true ) ) elseif rule['type'] == 'qualifier_max' then table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], false ) ) elseif rule['type'] == 'value' then table.insert( newClaims, p.filterByValue( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'value_min' then table.insert( newClaims, p.filterUtter( claims, true ) ) elseif rule['type'] == 'value_max' then table.insert( newClaims, p.filterUtter( claims, false ) ) end end claims = {} --[[ Merge all claims TODO: It's not good ]] for j, newSubClaims in ipairs( newClaims ) do for k, newClaim in ipairs( newSubClaims ) do local isNew = true for l, oldClaim in ipairs( claims ) do if oldClaim['id'] == newClaim['id'] then isNew = false break end end if isNew then table.insert( claims, newClaim ) end end end end return claims end --[[ Filter statements by rank Input: claims table, rank value, inversion Output: filtered statements table ]] function p.filterByRank( claims, rank, inversed ) if not inversed then inversed = false end if not rank then rank = 'best' end -- Check if rank value is valid local isValidRank = false for i, validRank in ipairs( validRanks ) do if rank == validRank then isValidRank = true break end end if not isValidRank then throwError( 'rank-not-valid' ) end -- Find the best rank if rank == 'best' then rank = 'normal' -- default rank (don't use deprecated even if it's no more claims) -- If we have at least one preferred rank, mark it as best for i, statement in pairs( claims ) do if (statement.rank == 'preferred') then rank = 'preferred' break end end end local resultClaims = {}; for i, statement in pairs( claims ) do if ( statement.rank == rank ) ~= inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Filter statements by language of value Input: claims table, language, inversion Output: filtered statements table ]] function p.filterByLanguage( claims, language, inversed ) if not inversed then inversed = false end local resultClaims = {} local mulStatement = {} for i, statement in ipairs( claims ) do isMatchLanguage = false if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['value'] and statement['mainsnak']['datavalue']['value']['language'] then if statement['mainsnak']['datavalue']['value']['language'] == language then isMatchLanguage = true end if statement['mainsnak']['datavalue']['value']['language'] == 'mul' then mulStatement = statement end end if isMatchLanguage ~= inversed then table.insert( resultClaims, statement ) end end if next(resultClaims) == nil and next(mulStatement) ~= nil then -- if specific language is not found, but there is Q20923490 value table.insert( resultClaims, mulStatement ) end return resultClaims end --[[ Filter statements by unit of value Input: claims table, unit, inversion Output: filtered statements table ]] function p.filterByUnit( claims, unit, inversed ) if not inversed then inversed = false end unit = 'http://www.wikidata.org/entity/' .. string.upper( unit ) local resultClaims = {} for i, statement in ipairs( claims ) do isMatchUnit = false if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['value'] and statement['mainsnak']['datavalue']['value']['unit'] and statement['mainsnak']['datavalue']['value']['unit'] == unit then isMatchUnit = true end if isMatchUnit ~= inversed then table.insert( resultClaims, statement ) break end end return resultClaims end --[[ Filter statements by position Input: claims table, position, inversion Output: filtered statements table ]] function p.filterByPosition( claims, position, inversed ) if not inversed then inversed = false end local resultClaims = {}; for statementPosition, statement in ipairs( claims ) do if ( statementPosition == tonumber( position ) ) ~= inversed then table.insert( resultClaims, statement ) break end end return resultClaims end --[[ Filter statements by qualifier existance or it's value Input: claims table, ID of qualifier's property, qualifier's value, inversion Output: filtered statements table ]] function p.filterByQualifier( claims, qualifierId, value, inversed ) if not inversed then inversed = false end qualifierId = string.upper( qualifierId ) local resultClaims = {} for i, statement in ipairs( claims ) do if statement['qualifiers'] and statement['qualifiers'][qualifierId] then if value == nil then if ( #statement['qualifiers'][qualifierId] > 0 ) ~= inversed then table.insert( resultClaims, statement ) end else local isQualifierFound = false for j, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do if qualifier['datavalue'] then local qualifierValue = qualifier['datavalue']['value'] if qualifier['datavalue']['type'] == 'wikibase-entityid' then qualifierValue = qualifierValue.id value = string.upper( value ) end if qualifierValue == value then isQualifierFound = true break end end end if isQualifierFound ~= inversed then table.insert( resultClaims, statement ) end end elseif inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Filter statements by it's values Input: claims table, value, inversed Output: filtered statements table ]] function p.filterByValue( claims, value, inversed ) inversed = inversed or false local resultClaims = {} for i, statement in ipairs( claims ) do local statementValue if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['type'] then statementValue = statement['mainsnak']['datavalue']['value'] if statement['mainsnak']['datavalue']['type'] == 'quantity' then statementValue = statementValue.amount end if statement['mainsnak']['datavalue']['type'] == 'time' then statementValue = statementValue.time end if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then statementValue = statementValue.id value = string.upper( value ) end end if ( statementValue == value ) ~= inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Find a statement with minimum or maximum value Input: claims table, asc, inversed Output: filtered statements table ]] function p.filterUtter( claims, asc, inversed ) local resultValue = nil for i, statement in ipairs( claims ) do local statementValue if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['type'] then statementValue = statement['mainsnak']['datavalue']['value'] if statement['mainsnak']['datavalue']['type'] == 'quantity' then statementValue = statementValue.amount end if statement['mainsnak']['datavalue']['type'] == 'time' then statementValue = statementValue.time end if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then statementValue = statementValue.id end if not resultValue or ( statementValue < resultValue ) == asc then resultValue = statementValue end end end mw.logObject( resultValue, 'resultValue' ) return p.filterByValue( claims, resultValue, inversed ) end --[[ Find a statement with minimum or maximum qualifier value Input: claims table, qualifierId, asc Output: filtered statements table ]] function p.filterUtterByQualifier( claims, qualifierId, asc ) qualifierId = string.upper( qualifierId ) local resultValue = nil local resultStatement = nil for i, statement in ipairs( claims ) do if not statement['qualifiers'] and not statement['qualifiers'][qualifierId] then if resultStatement == nil then resultStatement = statement end else for _, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do if qualifier['datavalue'] then local qualifierValue = qualifier['datavalue']['value'] if qualifier['datavalue']['type'] == 'quantity' then qualifierValue = qualifierValue.amount end if qualifier['datavalue']['type'] == 'time' then qualifierValue = qualifierValue.time end if qualifier['datavalue']['type'] == 'wikibase-entityid' then qualifierValue = qualifierValue.id end if not resultValue or ( qualifierValue < resultValue ) == asc then resultStatement = statement resultValue = qualifierValue end end end end end return { resultStatement } end return p 0bdff3a63bf171160cdec5c966211fbbf3003880 Модуль:Wikidata/config 828 85 181 180 2025-01-31T15:24:24Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain -- Property configuration for Wikidata module return { global = { separator = ',&#32;', conjunction = '&#32;и&#32;', }, presets = { ['catonly'] = { datatype = 'wikibase-item', conjunction = '', invisible = true, ['value-module'] = 'Wikidata/item', ['value-function'] = 'formatCategoryOnly', references = '', category = 'P910', }, ['country'] = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/Places', ['claim-function'] = 'formatCountryClaimWithFlag', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['from-to'] = { datatype = 'time', ['property-module'] = 'Wikidata/date', ['property-function'] = 'formatDateIntervalProperty', }, ['link'] = { ['value-module'] = 'Wikidata/link', ['value-function'] = 'fromModule', }, ['list'] = { before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['name'] = { datatype = 'monolingualtext', monolingualLangTemplate = 'lang', separator = '<br>', conjunction = '<br>', }, ['place'] = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/Places', ['claim-function'] = 'formatPlaceWithQualifiers', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['quantity (date)'] = { datatype = 'quantity', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', qualifier = 'P585', }, }, datatypes = { commonsMedia = { limit = 1, references = false, size = '274x400px', separator = '<br>', conjunction = '<br>', somevalue = '', ['value-module'] = 'Wikidata/media', ['value-function'] = 'formatCommonsMediaValue', }, ['external-id'] = { references = false, }, ['globe-coordinate'] = { limit = 1, references = false, }, url = { separator = '<br>', conjunction = '<br>', references = false, ['value-module'] = 'Wikidata/url', ['value-function'] = 'formatUrlValue', }, quantity = { siConversion = true } }, properties = { P6 = { datatype = 'wikibase-item', }, P17 = { preset = 'country', }, P18 = { datatype = 'commonsMedia', fixdouble = true, }, P19 = { preset = 'place', separator = ',</li><li>', conjunction = ' или </li><li>', }, P20 = { preset = 'place', separator = ',</li><li>', conjunction = ' или </li><li>', }, P22 = { datatype = 'wikibase-item', conjunction = ' или ' }, P25 = { datatype = 'wikibase-item', conjunction = ' или ' }, P26 = { datatype = 'wikibase-item', }, P27 = { preset = 'country', }, P31 = { datatype = 'wikibase-item', references = false, }, P37 = { datatype = 'wikibase-item', }, P39 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/positions', ['claim-function'] = 'formatPositionClaim', separator = '', conjunction = '', allowTables = true, }, P40 = { datatype = 'wikibase-item', }, P41 = { datatype = 'commonsMedia', size = '150x200px', }, P53 = { datatype = 'wikibase-item', category = 'P910', }, P54 = { category = 'P6112', }, P57 = { datatype = 'wikibase-item', preset = 'list', }, P58 = { datatype = 'wikibase-item', preset = 'list', }, P59 = { datatype = 'wikibase-item', category = 'P910', references = false, }, P69 = { datatype = 'wikibase-item', preset = 'list', category = 'P3876', qualifier = 'P582', }, P94 = { datatype = 'commonsMedia', size = '100x200px', }, P86 = { datatype = 'wikibase-item', preset = 'list', }, P101 = { datatype = 'wikibase-item', }, P102 = { datatype = 'wikibase-item', preset = 'list', qualifier = 'P582', category = 'P6365', }, P103 = { datatype = 'wikibase-item', }, P106 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'formatEntityWithGenderClaim', conjunction = ',&#32;', }, P108 = { datatype = 'wikibase-item', preset = 'list', category = 'P4195', }, P109 = { datatype = 'commonsMedia', size = '150x150px', alt = 'Изображение автографа', }, P117 = { datatype = 'commonsMedia', size = '290x300px', alt = 'Изображение химической структуры', }, P119 = { preset = 'place', thisLocationOnly = 'true', }, P131 = { datatype = 'wikibase-item', }, P140 = { datatype = 'wikibase-item', }, P154 = { size = '220x80px', alt = 'Изображение логотипа', }, P159 = { preset = 'place', }, P161 = { preset = 'list', }, P162 = { preset = 'list', }, P163 = { datatype = 'wikibase-item', }, P166 = { datatype = 'wikibase-item', ['property-module'] = 'Wikidata/Medals', ['property-function'] = 'formatProperty', ['value-module'] = 'Wikidata/Medals', ['value-function'] = 'formatValue', before = '<div style="text-align:justify">', after = '</div>', separator = '&#32;', conjunction = '&#32;', references = false, allowTables = true, }, P190 = { datatype = 'wikibase-item', }, P212 = { preset = 'link', }, P225 = { preset = 'list', ['claim-module'] = 'Wikidata/Biology', ['claim-function'] = 'formatTaxonNameClaim', }, P237 = { datatype = 'wikibase-item', }, P241 = { datatype = 'wikibase-item', }, P242 = { datatype = 'commonsMedia', size = '300x300px', }, P247 = { formatter = 'https://nssdc.gsfc.nasa.gov/nmc/spacecraft/display.action?id=$1', }, P267 = { preset = 'link', }, P276 = { preset = 'place', }, P281 = { datatype = 'string', }, P286 = { preset = 'list', }, P296 = { formatter = 'http://osm.sbin.ru/esr/esr:$1', }, P301 = { rawArticle = true, }, P344 = { preset = 'list', }, P345 = { preset = 'link', }, P348 = { preset = 'list', ['property-module'] = 'Wikidata/Software', ['property-function'] = 'formatVersionProperty', }, P361 = { datatype = 'wikibase-item', }, P373 = { datatype = 'string', ['value-module'] = 'Wikidata/media', ['value-function'] = 'formatCommonsCategory', limit = 1, references = false, }, P374 = { datatype = 'external-id', }, P395 = { datatype = 'string', }, P407 = { datatype = 'wikibase-item', }, P410 = { datatype = 'wikibase-item', }, P412 = { datatype = 'wikibase-item', category = 'P910', }, P413 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'formatEntityWithGenderClaim', conjunction = ',&#32;', category = 'P910', }, P414 = { ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'applyDefaultTemplate', }, P421 = { datatype = 'wikibase-item', }, P473 = { datatype = 'string', }, P495 = { preset = 'country', }, P505 = { preset = 'list', }, P512 = { datatype = 'wikibase-item', ['property-module'] = 'Wikidata/P512', ['property-function'] = 'formatAcademicDegree', }, P527 = { preset = 'list', }, P528 = { references = false, qualifier = 'P972', }, P551 = { preset = 'place', }, P569 = { datatype = 'time', ['claim-module'] = 'Wikidata/date', ['claim-function'] = 'formatDateOfBirthClaim', }, P570 = { datatype = 'time', ['claim-module'] = 'Wikidata/date', ['claim-function'] = 'formatDateOfDeathClaim', }, P571 = { datatype = 'time', }, P576 = { datatype = 'time', }, P598 = { datatype = 'wikibase-item', }, P607 = { datatype = 'wikibase-item', preset = 'list', }, P625 = { datatype = 'globe-coordinate', }, P669 = { qualifier = 'P670', }, P685 = { formatter = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=$1', }, P721 = { preset = 'link', }, P764 = { preset = 'link', }, P803 = { datatype = 'wikibase-item', }, P856 = { datatype = 'url', }, P881 = { novalue = 'нет', category = 'P910', }, P884 = { preset = 'link', }, P915 = { category = 'P1740', }, P957 = { preset = 'link', }, P972 = { preset = 'catonly', }, P1077 = { preset = 'link', }, P1082 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1098 = { preset = 'quantity (date)', unit = 'чел.', }, P1120 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1128 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1114 = { datatype = 'quantity', qualifier = 'P585', }, P1174 = { preset = 'quantity (date)', unit = 'чел.', }, P1195 = { ['value-module'] = 'Wikidata/Software', ['value-function'] = 'formatExtension', conjunction = ' или ', }, P1215 = { datatype = 'quantity', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatVisualMagnitude' }, P1246 = { preset = 'link', }, P1249 = { datatype = 'time', }, P1352 = { preset = 'quantity (date)', }, P1376 = { datatype = 'wikibase-item', }, P1402 = { preset = 'link', }, P1448 = { preset = 'name', }, P1458 = { datatype = 'quantity', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatColorIndex' }, P1464 = { datatype = 'wikibase-item', }, P1476 = { preset = 'name', }, P1477 = { preset = 'name', }, P1532 = { preset = 'country', rank = '[rank:normal, rank:preferred]', }, P1543 = { datatype = 'commonsMedia', }, P1559 = { preset = 'name', }, P1603 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1621 = { size = '300x300px', }, P1692 = { preset = 'link', }, P1705 = { preset = 'name', }, P1753 = { rowArticle = true, }, P1809 = { preset = 'list', }, P1846 = { datatype = 'commonsMedia', fixdouble = true, }, P2031 = { preset = 'from-to', to = 'P2032', within = 'P570', }, P2043 = { preset = 'quantity (date)', }, P2044 = { datatype = 'quantity', }, P2046 = { preset = 'quantity (date)', siConversion = false, }, P2047 = { siConversion = false, }, P2048 = { conjunction = '&#32;или&#32;', }, P2060 = { siConversion = false, }, P2097 = { siConversion = false, }, P2120 = { siConversion = false, }, P2137 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2139 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2146 = { siConversion = false, }, P2214 = { siConversion = false }, P2226 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2257 = { siConversion = false }, P2260 = { siConversion = false }, P2295 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2324 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.' }, P2403 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2425 = { alt = 'Изображение орденской планки', }, P2583 = { siConversion = false, }, P2597 = { preset = 'catonly', }, P2650 = { datatype = 'wikibase-item', }, P2789 = { preset = 'list', }, P2896 = { siConversion = false, }, P2910 = { size = '100x80px', }, P3083 = { formatter = 'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=$1', }, P3086 = { siConversion = false, }, P3362 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P4614 = { category = 'P1200', }, P5348 = { siConversion = false, }, P6257 = { ['value-module'] = 'Wikidata/number', ['value-function'] = 'formatRA', }, P6258 = { ['value-module'] = 'Wikidata/number', ['value-function'] = 'formatDMS', }, P6259 = { ['references'] = false, }, P7584 = { siConversion = false, }, P8010 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P8224 = { alt = 'Изображение молекулярной модели', }, }, categories = { ['links-to-entities-with-missing-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без подписи', ['links-to-entities-with-wikibase-error'] = 'Википедия:Страницы с ошибками скриптов, использующих Викиданные', ['links-to-entities-with-missing-local-language-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без русской подписи', ['media-contains-local-caption'] = 'Википедия:Локальная подпись у изображения из Викиданных', ['media-contains-markup'] = 'Википедия:Статьи с вики-разметкой в изображении карточки', ['media-contains-local-double'] = 'Википедия:Изображение в статье дублирует изображение в карточке', ['value-contains-table'] = 'Википедия:Статьи с табличной вставкой в карточке', }, errors = { ['property-param-not-provided'] = 'Не дан параметр свойства', ['entity-not-found'] = 'Сущность не найдена.', ['unknown-claim-type'] = 'Неизвестный тип заявления.', ['unknown-snak-type'] = 'Неизвестный тип снэка.', ['unknown-datavalue-type'] = 'Неизвестный тип значения данных.', ['unknown-entity-type'] = 'Неизвестный тип сущности.', ['unknown-property-module'] = 'Вы должны установить и property-module, и property-function.', ['unknown-claim-module'] = 'Вы должны установить и claim-module, и claim-function.', ['unknown-value-module'] = 'Вы должны установить и value-module, и value-function.', ['property-module-not-found'] = 'Модуль для отображения свойства не найден', ['property-function-not-found'] = 'Функция для отображения свойства не найдена', ['claim-module-not-found'] = 'Модуль для отображения утверждения не найден.', ['claim-function-not-found'] = 'Функция для отображения утверждения не найдена.', ['value-module-not-found'] = 'Модуль для отображения значения не найден.', ['value-function-not-found'] = 'Функция для отображения значения не найдена.', }, i18n = { somevalue = "''неизвестно''", novalue = '', -- Обстоятельства источника Q5727902 = 'около ', Q18122778 = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп.</span> ', Q30230067 = 'возможно ', Q52834024 = '<span style="border-bottom: 1px dotted; cursor: help;" title="менее чем">&lt;</span> ', Q54418095 = '<span style="border-bottom: 1px dotted; cursor: help;" title="более чем">&gt;</span> ', Q60070514 = 'примерно ', thousandPowers = {'', ' тыс.', ' млн', ' млрд', ' трлн'}, }, deprecatedSources = { Q355 = true, -- Facebook Q36578 = true, -- Gemeinsame Normdatei Q63056 = true, -- Find a Grave Q212256 = true, -- АиФ Q504063 = true, -- Discogs Q523660 = true, -- International Music Score Library Project by https://ru.wikipedia.org/?diff=107090748 Q1798125 = true, -- LIBRIS Q2621214 = true, -- Geni Q15222191 = true, -- BNF Q15241312 = true, -- Freebase Q19938912 = true, -- BNF Q21697707 = true, -- Хайазг Q25328680 = true, -- Prabook Q29861311 = true, -- SNAC Q86999151 = true, -- WeChangEd }, }; bd6091486f675bebf109cb52de53a162b05a5243 Шаблон:Nobr 10 86 183 182 2025-01-31T15:24:24Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly><span class="nowrap">{{{1}}}</span></includeonly><noinclude> {{doc}} <!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --> </noinclude> 989c6f164ed3a8543e916c8f1746ba1ab94fb068 Шаблон:If-wikidata 10 87 185 184 2025-01-31T15:24:25Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{#switch:{{wikidata|{{{1|}}}|{{{2|}}}|plain={{{plain|true}}}|from={{{from|}}}|somevalue={{{somevalue|}}}|novalue={{{novalue|}}}}}|значение отсутствует|={{{4|}}}|#default={{{3}}}}}<noinclude> {{doc}} </noinclude> a8a37fd2c4f1a266ec48783d7d0ad22cdcd812cb Модуль:Wikidata/media 828 88 187 186 2025-01-31T15:24:25Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local p = {} -- Константы local contentLanguageCode = mw.getContentLanguage():getCode(); function p.formatCommonsCategory( context, options, value ) local link = 'commons:Category:' .. value local title = value .. ' на Викискладе' if ( options['text'] and options['text'] ~= '' ) then title = options['text'] end commons = '[[' .. link .. '|' .. title .. ']]' --Commons icon if ( not options['icon'] or options['icon'] ~= '-' ) then local icon_size = '15px' if ( options['icon_size'] and options['icon_size'] ~= '' ) then icon_size = options['icon_size'] end commons = '[[File:Commons-logo.svg|' .. icon_size .. '|link=' .. link .. '|alt=Логотип Викисклада]] ' .. commons end --Text before and after link if ( options['text_before'] and options['text_before'] ~= '' ) then if ( options['text_before'] ~= '-' ) then commons = options['text_before'] .. ' ' .. commons end end if ( options['text_after'] and options['text_after'] ~= '' ) then if ( options['text_after'] ~= '-' ) then commons = commons .. ' ' .. options['text_after'] end end return commons end --[[ Временный хак, нужно добавить config, getConfig и getCategoryByCode в options, чтобы они были доступны в любом месте кода. ]] local config; local function getCategoryByCode( code, sortkey ) if config == nil then config = require( 'Module:Wikidata/config' ); end; local value = config[ 'categories' ][ code ]; if not value or value == '' then return ''; end return '[[Category:' .. value .. ']]'; end local function getCaption( context, options ) local caption = '' if options.qualifiers and options.qualifiers.P2096 then for i, qualifier in pairs( options.qualifiers.P2096 ) do if ( qualifier and qualifier.datavalue and qualifier.datavalue.type == 'monolingualtext' and qualifier.datavalue.value and qualifier.datavalue.value.language == contentLanguageCode ) then caption = qualifier.datavalue.value.text break end end end if options['appendTimestamp'] and options.qualifiers and options.qualifiers.P585 and options.qualifiers.P585[1] then local moment = context.formatValueDefault( context, options, options.qualifiers.P585[1].datavalue ) if not caption or caption == '' then caption = moment else caption = caption .. ', ' .. moment end end local localValue = ''; if options[ 'value' ] and options[ 'value' ] ~= '' then localValue = options[ 'value' ]; end local localCaption = ''; if options[ 'caption' ] and options[ 'caption' ] ~= '' then localCaption = options[ 'caption' ]; end if localValue ~= '' then caption = localCaption; end local formattedCaption = '' if caption ~= '' then formattedCaption = context.wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } ); end if localValue == '' and localCaption ~= '' then formattedCaption = formattedCaption .. getCategoryByCode( 'media-contains-local-caption' ) if options.frame:preprocess('{{REVISIONID}}') == '' then formattedCaption = formattedCaption .. '<span class="error" style="font-size:94%;">Локальная подпись не используется, потому что изображение берётся из Викиданных, см. [[Википедия:Шаблоны-карточки#Описание изображения в Викиданных|здесь]]</span>' end end return caption, formattedCaption end function p.formatCommonsMediaValue( context, options, value ) local image = value; local caption, formattedCaption = getCaption( context, options ) if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then -- если в value не содержится викикод или imagemap, то викифицируем имя файла -- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[PHAB:T28213]] image = '[[File:' .. value .. '|frameless'; if options[ 'border' ] and options[ 'border' ] ~= '' then image = image .. '|border'; end local size = options[ 'size' ]; if size and size ~= '' then if not string.match( size, 'px$' ) and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики then size = size .. 'px' end -- временно if string.match( size, 'pxpx' ) then image = '[[Категория:Википедия:Изображение с pxpx в размере]]' .. image end else size = fileDefaultSize; end image = image .. '|' .. size; if options[ 'alt' ] and options[ 'alt' ] ~= '' then image = image .. '|alt=' .. options[ 'alt' ]; end if caption ~= '' then image = image .. '|' .. caption end image = image .. ']]'; if formattedCaption ~= '' then image = image .. '<br>' .. formattedCaption; end else image = image .. formattedCaption .. getCategoryByCode( 'media-contains-markup' ); end if options.entity and options.fixdouble then local page = mw.title.getCurrentTitle() local txt = page:getContent() if txt and txt:match(':' .. value) and mw.title.getCurrentTitle():inNamespace(0) then if options.frame:preprocess('{{REVISIONID}}') == '' then image = image .. '<span class="error">Это изображение встречается ниже по тексту статьи; пожалуйста, уберите одну из копий (не потеряв при этом подпись)</span>' end image = image .. getCategoryByCode( 'media-contains-local-double' ) end end return image end return p ec384e72491465f4103cce95a8f9467df428a432 Шаблон:Карточка/оригинал названия 10 89 189 188 2025-01-31T15:24:25Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{wikidata|p1705[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<!-- -->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом названия без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude> 4eccda042428e1113ff320ff5d6b760a7f52b088 Шаблон:Br separated entries 10 90 191 190 2025-01-31T15:24:26Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude> {{doc}} </noinclude> 2113c3c6e95a84235b9f7a85e7ea17208e8f91df Шаблон:Карточка/блок с маркерами 10 91 193 192 2025-01-31T15:24:26Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{#invoke:Infobox/bulleted block|main}}<noinclude>{{doc}}</noinclude> 71e7755aa4fb1e445f008da13d6fa4212aea3c38 Шаблон:Карточка/блок 10 92 195 194 2025-01-31T15:24:26Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{#invoke:Infobox|renderLines}}</includeonly><noinclude>{{doc}}</noinclude> b76f4bc95a8a44fea1fa0f577d84111b51ce1385 Модуль:Infobox/bulleted block 828 93 197 196 2025-01-31T15:24:26Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local p = {} -- takes strings or nils; returns a string function makeText(frame, text, wikidata, from) if wikidata and wikidata ~= ''then return frame:expandTemplate{title='Wikidata', args={wikidata, text or '', from=from or ''}} else return text or '' end end -- from [[ru:Модуль:Infobox]] local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.main(frame) local args = frame:getParent().args local maxNumberArgs = maxNumber(args) local texts = {} for i = 1, maxNumberArgs do if args['текст' .. i] then texts[i] = makeText(frame, args['текст' .. i], args['викиданные' .. i], args['from']) end end local textsAreEmpty = true for i = 1, maxNumberArgs do if texts[i] and texts[i] ~= '' then textsAreEmpty = false end end local results = {} if not textsAreEmpty and args['подзаголовок'] and args['подзаголовок'] ~= '' then results['текст1'] = args['подзаголовок'] results['стиль_текста1'] = 'padding-bottom:0; border-bottom:0; text-align:left; font-weight:bold;' end local mainText = makeText(frame, args['текст'], args['викиданные'], args['from']) if mainText == '' and args['метка'] and args['метка'] ~= '' and not textsAreEmpty then mainText = '&nbsp;' end if mainText and mainText ~= '' then results['метка2'] = args['метка'] results['стиль_метки2'] = 'padding-bottom:0; border-bottom:0;' results['текст2'] = mainText results['стиль_текста2'] = 'padding-bottom:0; border-bottom:0;' end for i = 1, maxNumberArgs do if texts[i] and texts[i] ~= '' then results['метка' .. (i+2)] = '&nbsp;•&nbsp;' .. (args['метка' .. i] or '') results['текст' .. (i+2)] = texts[i] local last = true for j = i+1, maxNumberArgs do if texts[j] and texts[j] ~= '' then last = false end end if last then results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-top:0; border-top:0;' results['стиль_текста' .. (i+2)] = 'padding-top:0; border-top:0;' else results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;' results['стиль_текста' .. (i+2)] = 'padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;' end end end return frame:expandTemplate{title='Карточка/блок', args=results} end return p 856b97606e1f2809c940e384f6fe71a575ca019e Шаблон:Число 10 94 199 198 2025-01-31T15:24:27Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{formatnum: {{replace|{{{1}}}|,|.}} }}{{#if: {{{1|}}} | {{#if: {{{2|}}} | {{nobr|1=&nbsp;{{{2|}}}}} }} }}<noinclude> {{doc}} </noinclude> acfc1e9cec817e6742b18106f020ac388ececc7e Модуль:Wikidata/count 828 95 201 200 2025-01-31T15:24:27Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local p = {} function p.getCount( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; local claims; if options.property then -- TODO: Почему тут может не быть property? claims = context.selectClaims( options, options.property ); end if claims == nil then return ''; --TODO error? end return table.getn(claims); end function p.isMultiple( context, options ) local count = p.getCount( context, options ); local multiple = ''; if( count ~= nil and count ~= '' and count > 1 ) then multiple = 1; end return multiple; end return p 8ccf5dd7170a466674627b0afdf32c6bd2318154 Шаблон:Без начала 10 96 203 202 2025-01-31T15:24:28Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#ifeq:{{<includeonly>safesubst:</includeonly>Str_left|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}*|{{{2}}}*|{{<includeonly>safesubst:</includeonly>Str_right|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}|{{{1}}}}}<noinclude>{{doc}}</noinclude> 9fbca6f1fc236cb17fe77d76891e3f9c2afa2117 Шаблон:Карточка/официальное название 10 97 205 204 2025-01-31T15:24:28Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{wikidata|p1448[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<noinclude>{{doc}}</noinclude> 708a700c58a199343531d8fb3eec7ee897e92732 Шаблон:Карточка/флаг и герб 10 98 207 206 2025-01-31T15:24:29Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<templatestyles src="Шаблон:Карточка/styles.css" /><table role="presentation" class="ts-infobox-flaginfo"> <tr> {{if-wikidata|p41|{{{флаг|}}}|<td>{{wikidata|p41|{{{флаг|}}}|from={{{from|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}} {{if-wikidata|p94|{{{герб|}}}|<td>{{wikidata|p94|{{{герб|}}}|from={{{from|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}} </tr> {{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<tr> {{if-wikidata|p41|{{{флаг|}}}|3=<td class="media-caption">{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}} {{if-wikidata|p94|{{{герб|}}}|3=<td class="media-caption">{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}} </tr>}}</table> }}<noinclude> {{doc}} </noinclude> 1790949866597b0909572cd51fdfb8b9a7db55ff Шаблон:Lang-sv 10 99 209 208 2025-01-31T15:24:29Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki [[шведский язык|швед.]] {{langi|sv|{{{1}}}}}<noinclude>{{doc|Lang/doc}} </noinclude> c4b5e81c6405972dcea4cc26ab77e99e9bd2021f Шаблон:Население государства 10 100 211 210 2025-01-31T15:24:29Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki <includeonly>{{#switch: {{{1}}} | Республика Южная Осетия = Население Южной Осетии{{!}}Население | Население }}</includeonly><noinclude> {{doc}} [[Категория:Шаблоны по странам]] </noinclude> e0568280ef5056e94f5f1abf1934f4188a52c35f Шаблон:Lang-fi 10 101 213 212 2025-01-31T15:24:30Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki [[финский язык|фин.]] {{langi|fi|{{{1}}}}}<noinclude>{{doc|Lang/doc}} </noinclude> 16ac91b8e1e294e7687d57c0757c178f9662581c Шаблон:Demo 10 102 215 214 2025-01-31T15:24:30Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{#invoke:Demo|main}}<noinclude>{{documentation}}</noinclude> e458e378477c6077a01987f334fdc73bee48512c Модуль:Demo 828 103 217 216 2025-01-31T15:24:30Z Генерал Альдации 2 1 версия импортирована Scribunto text/plain local p = {} local getArgs = require('Модуль:Arguments').getArgs local function hasValue(param) if param and param:find('%S') then return true end end --creates a frame object that cannot access any of the parent's args --unless a table containing a list keys of not to inherit is provided function disinherit(frame, onlyTheseKeys) local parent = frame:getParent() or frame local orphan = parent:newChild{} orphan.getParent = parent.getParent --returns nil orphan.args = {} if onlyTheseKeys then local family = {parent, frame} for f = 1, 2 do for k, v in pairs(family[f] and family[f].args or {}) do orphan.args[k] = orphan.args[k] or v end end parent.args = mw.clone(orphan.args) setmetatable(orphan.args, nil) for _, k in ipairs(onlyTheseKeys) do rawset(orphan.args, k, nil) end end return orphan, parent end function p.get(frame, arg, passArgs) local orphan, frame = disinherit(frame, passArgs and {arg or 1}) local code, noWiki, preserve = frame.args[arg or 1] or '' local kill_categories = not frame.args.save_categories local tag, sep if code:match'nowiki' then local placeholder, preserve = ('6'):char(), {} -- We replace "&#125;%-" and "%-&#123;" because of some server bug probably connected to -- [[mw:Parsoid/MediaWiki DOM spec/Language conversion blocks]] and leading to -- =mw.text.unstripNoWiki(mw.getCurrentFrame():preprocess('<nowiki>}-</nowiki>')) -- outputting '&#125;-' instead of "}-", while it's ok with "<nowiki>} -</nowiki>" code = mw.text.unstripNoWiki(code) :gsub('&lt;', '<') :gsub('&gt;', '>') :gsub('&#125;%-', '}-') :gsub('%-&#123;', '-{') if (mw.text.trim(code):match'\n') then tag = 'pre' sep = '' end noWiki = code:gsub('%%', placeholder) for k in noWiki:gmatch('&.-;') do table.insert(preserve, (k:gsub('&', '&amp;'))) noWiki = noWiki:gsub('(&.-;)', '%%%s') end noWiki = mw.text.nowiki(noWiki):format(unpack(preserve)):gsub(placeholder, '%%') end return { source = noWiki or code, output = orphan:preprocess(code) :gsub(kill_categories and '%[%[Категория:.-%]%]' or '', '') :gsub(kill_categories and '%[%[К:.-%]%]' or '', '') :gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''), frame = frame, args = getArgs(frame), tag = tag, sep = sep } end function p.main(frame, demoTable) local show = demoTable or p.get(frame) local args = show.args local yesno = require('Module:Yesno') args.reverse = yesno(args.reverse, false) args.tag = hasValue(args.tag) and args.tag or hasValue(show.tag) and show.tag or "code" args.sep = args.sep or args.br or show.sep args.sep = tonumber(args.sep) and ('<br>'):rep(args.sep or 0) or args.sep or (args.tag == 'pre' and '' or ' → ') if show[args.result_arg] then return show[args.result_arg] end return args.reverse and string.format( '%s%s<%s%s%s>%s</%s>', show.output, args.sep, args.tag, hasValue(args.class) and string.format(' class="%s"', args.class) or '', hasValue(args.style) and string.format(' style="%s"', args.style) or '', show.source, args.tag ) or string.format( '<%s%s%s>%s</%s>%s%s', args.tag, hasValue(args.class) and string.format(' class="%s"', args.class) or '', hasValue(args.style) and string.format(' style="%s"', args.style) or '', show.source, args.tag, args.sep, show.output ) end --passing of args into other module without preprocessing function p.module(frame) local orphan, frame = disinherit(frame, { 'demo_template', 'demo_module', 'demo_module_func', 'demo_main', 'demo_br', 'demo_result_arg', 'demo_save_categories' }) local template = frame.args.demo_template and 'Template:'..frame.args.demo_template local demoFunc = frame.args.demo_module_func or 'main\n' local demoModule = require('Module:' .. frame.args.demo_module)[demoFunc:match('^%s*(.-)%s*$')] frame.args.br, frame.args.result_arg = frame.args.demo_br or frame.args.demo_sep, frame.args.demo_result_arg local kill_categories = not save_categories if demoModule then local named = {insert = function(self, ...) table.insert(self, ...) return self end} local source = {insert = named.insert, '{{', frame.args.demo_template or frame.args.demo_module, '\n'} if not template then source:insert(2, '#invoke:'):insert(4, '|'):insert(5, demoFunc) end local insertNamed = #source + 1 for k, v in pairs(orphan.args) do local nan, insert = type(k) ~= 'number', {v} local target = nan and named or source target:insert'|' if nan then target:insert(k):insert'=':insert'\n' table.insert(insert, 1, #target) end target:insert(unpack(insert)) local nowiki = v:match('nowiki') if nowiki or v:match('{{.-}}') then orphan.args[k] = frame:preprocess(nowiki and mw.text.unstripNoWiki(v) or v) end end source:insert'}}' table.insert(source, insertNamed, table.concat(named)) return p.main(orphan, { source = mw.text.encode(table.concat(source), "<>'|=~"), output = tostring(demoModule(orphan)):gsub(kill_categories and '%[%[Категория:.-%]%]' or '', ''):gsub(kill_categories and '%[%[К:.-%]%]' or '', ''):gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''), frame = frame }) else return "ERROR: Invalid module function: "..demoFunc end end return p 9beaf8f8041a39ae73ba17b2f70609171c4196d3 Шаблон:Государство/doc 10 104 219 218 2025-01-31T15:24:30Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{docpage}} Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи о современных государствах; * для исторических государств используйте {{t|историческое государство}}. * для составных частей государств используйте {{t|Административная единица}}. == Образец для копирования == <pre> {{Государство |Статус = <!-- виртуальное / непризнанное / частично признанное / регион; для признанных государств не заполнять --> |Русское название = |Оригинальное название = |Родительный падеж = |Герб = |Вместо герба = |Девиз = {{lang-??2|}}<!-- на оф. языке / языках гос-ва --> |Перевод девиза = |Название гимна = |Перевод названия гимна = |Аудио = |Форма правления = |Государственный строй = |Государственная религия = |На карте = |подпись к карте = |На карте2 = |Язык/Языки = |Основано/Основана = |Дата/Даты независимости = |Независимость от = |Столица = |Крупнейшие города = |Должность руководителя 1 = |Руководитель 1 = |Должность руководителя 2 = |Руководитель 2 = |Должность руководителя 3 = |Руководитель 3 = |Должность руководителя 4 = |Руководитель 4 = |Должность руководителя 5 = |Руководитель 5 = |Место по территории = |Территория = |Процент воды = |Этнохороним = |Место по населению = |Население = |Год оценки = |Население по переписи = |Год переписи = |Плотность населения = |Место по плотности = |ВВП (ППС) = |Год расчёта ВВП (ППС) = |Место по ВВП (ППС) = |ВВП (ППС) на душу населения = |Место по ВВП (ППС) на душу населения = |ВВП (номинал) = |Год расчёта ВВП (номинал) = |Место по ВВП (номинал) = |ВВП (номинал) на душу населения = |Место по ВВП (номинал) на душу населения = |ИРЧП = |Год расчёта ИРЧП = |Место по ИРЧП = |Уровень ИРЧП = |Валюта = |Домен/Домены = |Телефонный код = |Часовой пояс = |Автомобильное движение = |Примечания = <!-- |Без флага и герба=* --> <!-- |Без гимна=* --> }} </pre> == Описание параметров == Некоторые параметры могут быть заданы в разных формах (например, в единственном либо множественном числе). После копирования образца в статью заполните только строку с более подходящей формой. Например, в статье [[Албания]]&nbsp;— <pre> |Язык = [[Албанский язык|албанский]]</pre> а в статье [[Канада]]&nbsp;— <pre> |Языки = [[Английский язык|английский]] и [[Французский язык|французский]]</pre> Для статей о регионах с нечётким правовым статусом используйте параметр <code>Спорный статус = да</code> и параметры «Основано», «Дата образования», «Провозглашение независимости» и «Дипломатическое признание» вместо «Дата независимости» и «Основано»: <pre> |Спорный статус = да |Основано = |Основана = |Дата образования = |Провозглашение независимости = |Дипломатическое признание = |Независимость от = </pre> Для статей о [[Непризнанные и частично признанные государства|непризнанных государствах]] или [[Автономный регион|автономных регионах]], не являющихся самостоятельными государствами, используйте параметр <code>Статус&nbsp;=&nbsp;непризнанное</code> или <code>Статус = регион</code>, это отключит автоматическое добавление категории [[:Категория:Государства по алфавиту|Государства по алфавиту]], а в первом случае также добавит категорию [[:Категория:Непризнанные государства|Непризнанные государства]]. Для статей о [[Виртуальное государство|виртуальных государствах]] используйте параметр <code>Статус = виртуальное</code>, это добавит категорию [[:Категория:Виртуальные государства|Виртуальные государства]]. == Пример использования == {{demo|reverse=1|br=|<nowiki>{{Государство |Русское название = Финляндская Республика |Оригинальное название = {{lang-fi|Suomen Tasavalta}}<br>{{lang-sv|Republiken Finland}} |Родительный падеж = Финляндии |Герб = Coat of arms of Finland.svg |Флаг = Flag of Finland.svg<!-- иначе используется конструкция {{флаг|{{FULLPAGENAME}}|размер=135px}} --> |Вместо герба = |Девиз = |Перевод девиза = |Название гимна = Maamme |Перевод названия гимна = Наш край |Аудио = |Форма правления = [[президентская республика]] |Государственный строй = [[унитарное государство]] |Государственная религия = |На карте = EU-Finland.svg |подпись к карте = Расположение '''Финляндии''' (тёмно-зелёный):<br>— в [[Европа|Европе]] (светло-зелёный и тёмно-серый)<br>— в [[Европейский союз|Европейском союзе]] (светло-зелёный) |На карте2 = |Языки = [[финский язык|финский]], [[шведский язык|шведский]] |Основано/Основана = |Дата независимости = [[6 декабря]] [[1917]] |Независимость от = [[Россия|России]] |Столица = [[Хельсинки]] |Крупнейший город = Хельсинки |Должность руководителя 1 = [[Президент Финляндии|Президент]] |Руководитель 1 = [[Халонен, Тарья Каарина|Тарья Халонен]] |Должность руководителя 2 = [[Премьер-министр Финляндии|Премьер-министр]] |Руководитель 2 = [[Ванханен, Матти Танели|Матти Ванханен]] |Место по территории = 63 |Территория = 338 145 |Процент воды = 9,96 |Этнохороним = финляндец, финляндка |Место по населению = 106 |Население = 5 219 732 |Год оценки = 2003 |Население по переписи = |Год переписи = |Плотность населения = 15,4 |Место по плотности = |ВВП = |Год расчёта ВВП = |Место по ВВП = |ВВП на душу населения = |Место по ВВП на душу населения = |ИРЧП = |Год расчёта ИРЧП = |Место по ИРЧП = |Уровень ИРЧП = |Валюта = [[евро]]<ref name="money">до 2002 — [[финская марка]]</ref> |Домены = [[.fi]], [[.ax]] (для [[Аландские острова|Аландских островов]]) |Телефонный код = 358 |Часовой пояс = +2 |Автомобильное движение = |Примечания = <references/> }}</nowiki>}} == TemplateData == <templatedata> { "params": { "Спорный статус": {}, "Статус": {}, "Русское название": {}, "Оригинальное название": {}, "Флаг": { "type": "wiki-file-name" }, "Ссылка на флаг": {}, "Родительный падеж": {}, "Герб": { "type": "wiki-file-name" }, "Отображаемая подпись герба": {}, "Вместо герба": {}, "Девиз": {}, "Перевод девиза": {}, "Без гимна": {}, "Название гимна": {}, "Перевод названия гимна": {}, "Аудио": {}, "На карте": {}, "На карте2": {}, "Дата1": {}, "Дата2": {}, "Дата3": {}, "Дата4": {}, "Дата5": {}, "Дата6": {}, "Дата7": {}, "Дата8": {}, "Дата9": {}, "Дата10": {}, "Дата11": {}, "Дата12": {}, "sovereignty_type": {}, "Этап1": {}, "Этап2": {}, "Этап3": {}, "Этап4": {}, "Этап5": {}, "Этап6": {}, "Этап7": {}, "Этап8": {}, "Этап9": {}, "Этап10": {}, "Этап11": {}, "Этап12": {}, "Основана": {}, "Основано": {}, "Дата образования": {}, "Провозглашение независимости": {}, "Независимость от": {}, "Дипломатическое признание": {}, "Отображаемый тип независимости": {}, "Даты независимости": {}, "Дата независимости": {}, "Язык": {}, "Языки": {}, "Столица": {}, "Крупнейший город": {}, "Крупнейшие города": {}, "Форма правления": {}, "Должность руководителя 1": {}, "Должности руководителей": {}, "Руководитель 1": {}, "Руководители": {}, "Должность руководителя 2": {}, "Руководитель 2": {}, "Должность руководителя 3": {}, "Руководитель 3": {}, "Должность руководителя 4": {}, "Руководитель 4": {}, "Должность руководителя 5": {}, "Руководитель 5": {}, "Государственная религия": {}, "Место по территории": {}, "Территория": {}, "Процент воды": {}, "Территория2": {}, "Население": {}, "Год оценки": {}, "Год переписи": {}, "Население2": {}, "Место по населению": {}, "Население по переписи": {}, "Плотность населения": {}, "Место по плотности": {}, "ВВП": {}, "Год расчёта ВВП": {}, "Место по ВВП": {}, "ВВП на душу населения": {}, "Место по ВВП на душу населения": {}, "ВВП (ППС)": {}, "Год расчёта ВВП (ППС)": {}, "Место по ВВП (ППС)": {}, "ВВП (ППС) на душу населения": {}, "Место по ВВП (ППС) на душу населения": {}, "ВВП (номинал)": {}, "Год расчёта ВВП (номинал)": {}, "Место по ВВП (номинал)": {}, "ВВП (номинал) на душу населения": {}, "Место по ВВП (номинал) на душу населения": {}, "Год расчёта ИРЧП": {}, "ИРЧП": {}, "Уровень ИРЧП": {}, "Место по ИРЧП": {}, "Этнохороним": {}, "Валюта": {}, "Домены": {}, "Домен": {}, "Телефонный код": {}, "Часовые пояса": {}, "Часовой пояс": {}, "Примечания": {}, "nocat": { "type": "boolean" }, "lat_deg": {}, "lat_min": {}, "lat_sec": {}, "lat_dir": {}, "lon_deg": {}, "lon_min": {}, "lon_sec": {}, "lon_dir": {}, "region": {}, "CoordScale": {}, "Размер герба": { "aliases": [ "размер герба" ], "type": "number" }, "Размер флага": { "aliases": [ "размер флага" ], "type": "number" }, "Размер карты": { "aliases": [ "размер карты" ] }, "Подпись к карте": { "aliases": [ "подпись к карте" ] }, "Размер карты2": { "aliases": [ "размер карты2" ] }, "Государственный строй": {}, "Автомобильное движение": {} }, "paramOrder": [ "Статус", "Спорный статус", "Русское название", "Оригинальное название", "Флаг", "Размер флага", "Ссылка на флаг", "Родительный падеж", "Герб", "Размер герба", "Отображаемая подпись герба", "Вместо герба", "Девиз", "Перевод девиза", "Без гимна", "Название гимна", "Перевод названия гимна", "Аудио", "На карте", "Размер карты", "Подпись к карте", "На карте2", "Размер карты2", "Дата1", "Дата2", "Дата3", "Дата4", "Дата5", "Дата6", "Дата7", "Дата8", "Дата9", "Дата10", "Дата11", "Дата12", "sovereignty_type", "Этап1", "Этап2", "Этап3", "Этап4", "Этап5", "Этап6", "Этап7", "Этап8", "Этап9", "Этап10", "Этап11", "Этап12", "Основана", "Основано", "Дата образования", "Провозглашение независимости", "Независимость от", "Дипломатическое признание", "Отображаемый тип независимости", "Даты независимости", "Дата независимости", "Язык", "Языки", "Столица", "Крупнейший город", "Крупнейшие города", "Форма правления", "Государственный строй", "Должность руководителя 1", "Должности руководителей", "Руководитель 1", "Руководители", "Должность руководителя 2", "Руководитель 2", "Должность руководителя 3", "Руководитель 3", "Должность руководителя 4", "Руководитель 4", "Должность руководителя 5", "Руководитель 5", "Государственная религия", "Место по территории", "Территория", "Процент воды", "Территория2", "Население", "Год оценки", "Год переписи", "Население2", "Место по населению", "Население по переписи", "Плотность населения", "Место по плотности", "ВВП", "Год расчёта ВВП", "Место по ВВП", "ВВП на душу населения", "Место по ВВП на душу населения", "ВВП (ППС)", "Год расчёта ВВП (ППС)", "Место по ВВП (ППС)", "ВВП (ППС) на душу населения", "Место по ВВП (ППС) на душу населения", "ВВП (номинал)", "Год расчёта ВВП (номинал)", "Место по ВВП (номинал)", "ВВП (номинал) на душу населения", "Место по ВВП (номинал) на душу населения", "Год расчёта ИРЧП", "ИРЧП", "Уровень ИРЧП", "Место по ИРЧП", "Этнохороним", "Валюта", "Домены", "Домен", "Телефонный код", "Часовые пояса", "Часовой пояс", "Автомобильное движение", "Примечания", "lat_deg", "lat_min", "lat_sec", "lat_dir", "lon_deg", "lon_min", "lon_sec", "lon_dir", "region", "CoordScale", "nocat" ], "format": "block" } </templatedata> == См. также == * {{tl|Историческое государство}} <includeonly> [[Категория:Шаблоны-карточки:Географические объекты]] </includeonly> b1e2b1107db0671d3bcc4dda5bd29020192c442e Шаблон:Карточка/styles.css 10 105 221 220 2025-01-31T15:24:31Z Генерал Альдации 2 1 версия импортирована text text/plain /* Вынесено из [[MediaWiki:Common.css]] и [[MediaWiki:Mobile.css]] */ /* [[Шаблон:Карточка/флаг и герб]] */ .ts-infobox-flaginfo { background: none; border-collapse: collapse; display: table; text-align: center; width: 100%; } .ts-infobox-flaginfo td { vertical-align: middle; } body.skin--responsive.skin-minerva.skin-minerva .ts-infobox-flaginfo td { /* Минерва требует хаков, чтобы эти стили работали */ border-bottom: 0; vertical-align: middle; } /* Таблицы */ .infobox-table, .infobox-tablebox { padding: 0; } .infobox-inner-table, .infobox-table > table, .infobox-tablebox > table { width: 100%; display: table; margin: 0; background: transparent; } .infobox-tablebox > table { border: 1px solid var(--border-color-base, #a2a9b1); border-collapse: separate; } /* Встраиваемая карточка */ .infobox-child { width: 100%; margin: 0; padding: 0; border: none; font-size: 100%; } body.skin-minerva table.infobox-child { width: 100% !important; margin: 0 !important; padding: 0; border: none; font-size: 100%; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 25901ad6113ef3908fc70305ce64eb64925c665f Шаблон:Государство 10 106 223 222 2025-01-31T15:25:29Z Генерал Альдации 2 1 версия импортирована wikitext text/x-wiki {{Карточка |имя = Государство |автозаголовки = да |from = {{{from|}}} |вверху0 = {{#switch: {{{Статус|}}} | виртуальное = [[Виртуальное государство]] | особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }} | Непризнанное | непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }} | Частично признанное | частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }} }} |вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}} |вверху2 = {{карточка/оригинал названия|{{карточка/официальное название|{{{Оригинальное название|}}}|from={{{from|}}}}}|from={{{from|}}}}} |изображение = {{Карточка/флаг и герб | флаг = {{{Флаг|}}} | флаг ширина = {{{Размер флага|}}}{{{размер флага|}}} | флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]] | герб = {{{Герб|}}} | герб ширина = {{{Размер герба|}}}{{{размер герба|}}} | герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }} |from={{{from|}}}}} |текст1 = {{br separated entries | {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }} | {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }} }} |текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | {{br separated entries | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | {{#if: {{{Перевод названия гимна|}}} | ''«{{{Перевод названия гимна}}}»'' }} }} | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|center]] }} }} }} |текст3 = {{#if: {{wikidata|p242|{{{На карте|}}}|plain=true|from={{{from|}}}}} | {{wikidata|p242|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}|from={{{from|}}}}}<!-- -->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }} |заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }} |стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left; |блок5 = {{Карточка/блок с маркерами |метка1 = {{nobr|{{{Дата1}}}}} |текст1 = {{{Этап1|}}} |метка2 = {{nobr|{{{Дата2}}}}} |текст2 = {{{Этап2|}}} |метка3 = {{nobr|{{{Дата3}}}}} |текст3 = {{{Этап3|}}} |метка4 = {{nobr|{{{Дата4}}}}} |текст4 = {{{Этап4|}}} |метка5 = {{nobr|{{{Дата5}}}}} |текст5 = {{{Этап5|}}} |метка6 = {{nobr|{{{Дата6}}}}} |текст6 = {{{Этап6|}}} |метка7 = {{nobr|{{{Дата7}}}}} |текст7 = {{{Этап7|}}} |метка8 = {{nobr|{{{Дата8}}}}} |текст8 = {{{Этап8|}}} |метка9 = {{nobr|{{{Дата9}}}}} |текст9 = {{{Этап9|}}} |метка10 = {{nobr|{{{Дата10}}}}} |текст10 = {{{Этап10|}}} |метка11 = {{nobr|{{{Дата11}}}}} |текст11 = {{{Этап11|}}} |метка12 = {{nobr|{{{Дата12}}}}} |текст12 = {{{Этап12|}}} |from={{{from|}}}}} |заголовок6 = - |метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]] |текст7 = {{{Основана|}}}{{{Основано|}}} |викиданные7 = <!-- СПОРНЫЙ СТАТУС --> <!-- Спорный статус заполнен --> |метка8 = [[Основание государства|Дата образования]] |текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }} |викиданные8 = |метка9 = Провозглашение независимости |текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |викиданные9 = |метка10 = [[Международно-правовое признание|Дипломатическое признание]] |текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }} |викиданные10 = <!-- Спорный статус не заполнен --> |метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }} |текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |викиданные11 = <!-- / СПОРНЫЙ СТАТУС --> |метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]] |текст12 = {{{Язык|{{{Языки|}}}}}} |викиданные12 = p37 |метка13 = [[Столица]] |текст13 = {{{Столица|}}} |викиданные13 = p36 |метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }} |текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}} |викиданные14 = |метка15 = [[Форма государственного правления|Форма правления]] |текст15 = {{{Форма правления|}}} |викиданные15 = |метка16 = [[Форма государственного устройства|Государственный строй]] |текст16 = {{{Государственный строй|}}} |метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}} |текст17 = {{{Руководитель 1|{{{Руководители|}}}}}} |метка18 = {{{Должность руководителя 2}}} |текст18 = {{{Руководитель 2|}}} |метка19 = {{{Должность руководителя 3}}} |текст19 = {{{Руководитель 3|}}} |метка20 = {{{Должность руководителя 4}}} |текст20 = {{{Руководитель 4|}}} |метка21 = {{{Должность руководителя 5}}} |текст21 = {{{Руководитель 5|}}} |метка22 = {{{Должность руководителя 6}}} |текст22 = {{{Руководитель 6|}}} |метка23 = [[Государственная религия|Гос. религия]] |текст23 = {{{Государственная религия|}}} |викиданные23 = |блок24 = {{Карточка/блок с маркерами |подзаголовок = [[Территория государства|Территория]] |метка1 = Всего |текст1 = {{br separated entries | {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | &nbsp;{{nobr|([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]])}} }} | {{число|{{{Территория2|}}}|км²}} }} |метка2 = % водной поверхности |текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }} |from={{{from|}}}}} |блок25 = {{Карточка/блок с маркерами |подзаголовок = [[{{Население государства|{{PAGENAME}}}}]] |метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }} |текст1 = {{br separated entries | {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | &nbsp;([[Список стран по населению|{{{Место по населению}}}-е]]) }} | {{число|{{{Население2|}}}|чел.}} }} |метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }} |текст2 = {{число|{{{Население по переписи|}}}|чел.}} |метка3 = [[Плотность населения|Плотность]] |текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | &nbsp;([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }} |from={{{from|}}}}} |блок26 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] |метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }} |текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок27 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }} |текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок28 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }} |текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | &nbsp;([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | &nbsp;([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }} |from={{{from|}}}}} |метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }} |текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | &nbsp;({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | &#059; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е&nbsp;место]] }}) }} |викиданные29 = |метка30 = [[Названия жителей]] |текст30 = {{{Этнохороним|}}} |викиданные30 = |метка31 = [[Валюта]] |текст31 = {{{Валюта|}}} |викиданные31 = P38 |метка32 = [[Домен верхнего уровня|{{wikidata number switch|P78|{{{Домен|}}}|{{{Домены|}}}|Интернет-домен|Интернет-домены}}]] |текст32 = {{{Домен|}}}{{{Домены|}}} |викиданные32 = P78 |метка33 = [[ISO 3166-1|Код ISO]] |текст33 = |викиданные33 = P297 |метка34 = [[Список кодов МОК|Код МОК]] |текст34 = |викиданные34 = P984 |метка35 = [[Список телефонных кодов стран|Телефонный код]] |текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }} |викиданные35 = P474 |метка36 = [[Часовой пояс|{{wikidata number switch|P421|{{{Часовой пояс|}}}|{{{Часовые пояса|}}}|Часовой пояс|Часовые пояса}}]] |текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}} |викиданные36 = P421 |метка37 = Автомобильное движение |текст37 = {{{Автомобильное движение|}}} |викиданные37 = P1622 |текст38 = {{{Примечания|}}} |стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left; |внизу = {{карточка/Викисклад|from={{{from|}}}}} }}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#if: {{{lat_deg|}}} | {{coord|1={{{lat_deg|}}}|2={{{lat_min|0}}}|3={{{lat_sec|0}}}|4={{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }}|5={{{lon_deg|}}}|6={{{lon_min|0}}}|7={{{lon_sec|0}}}|8={{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }}|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|format=dms|display=title}} | {{#if: {{#property: p625}} | {{wikidata|p625|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|from={{{from|}}}}} | [[Категория:Государства без указанных географических координат]] }} }}<!-- -->{{#switch: {{{Статус|}}} | Виртуальное | виртуальное = [[Категория:Виртуальные государства]] | Непризнанное | непризнанное = [[Категория:Непризнанные государства]] | Частично признанное | частично признанное = [[Категория:Частично признанные государства]] | особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }} | [[Категория:Государства по алфавиту]] }}<!-- -->{{Государство/Викиданные}} }}<noinclude>{{doc}}</noinclude> d5532838af5967020fc4f653452458ba05aea4cf